﻿/**
 * @file cfg.c
 * @author septem (jsm920@outlook.com)
 * @brief 
 * @version 0.0.1
 * @date 2024-10-13
 * 
 * @copyright Copyright (c) 2024
 * 
 */
#include "cfg.h"
#if defined(_WIN32) && defined(_MSC_VER)
#include <stdio.h>
#include <string.h>
#include <ctype.h> // isdigit
#include <assert.h> // assert()
#include <math.h> //pow
#pragma warning( push )
#pragma warning( disable: 4244 ) // 禁用转换告警
#elif defined(__linux__)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h> // isspace
#include <math.h> //pow  /link -lm
#include <assert.h> // assert()

#endif
#define EOF_OF_BUF -3 // 遇到缓存结束
#define __new(cnt, T) (T *)malloc(sizeof(T) * cnt) /* 分配 cnt 个 T 类型的数据 not zeroed */
#define __delete(P) free((void *)(P)) 
#define __zero(P,cnt, T) memset((void *)(P), 0, sizeof(T)*cnt)

/**
 * @brief 简单的 utf16be转换到utf8，仅支持中英文，返回占用字节数，传入 utf8最少3个字节
 * 
 * @param utf16be 
 * @param utf8 用于返回地址
 * @return int 
 */
int Utf16BE2Utf8(unsigned short utf16be, char* utf8)
{
    // 码点的位数 	码点起值 	码点终值 		Byte 1 	Byte 2 	Byte 3 	Byte 4 	Byte 5 	Byte 6
    // 7 	U+0000 	U+007F 	1 	0xxxxxxx 					
    // 11 	U+0080 	U+07FF 	2 	110xxxxx 	10xxxxxx 				
    // 16 	U+0800 	U+FFFF 	3 	1110xxxx 	10xxxxxx 	10xxxxxx 			
    // 21 	U+10000 	U+1FFFFF 	4 	11110xxx 	10xxxxxx 	10xxxxxx 	10xxxxxx 		
    // 26 	U+200000 	U+3FFFFFF 	5 	111110xx 	10xxxxxx 	10xxxxxx 	10xxxxxx 	10xxxxxx 	
    // 31 	U+4000000 	U+7FFFFFFF 	6 	1111110x 	10xxxxxx 	10xxxxxx 	10xxxxxx 	10xxxxxx 	10xxxxxx
    if(utf16be <=0x7f)
    {
        utf8[0] = utf16be & 0x7f;
        return 1;
    }
    else if(utf16be <= 0x7ff)
    {
        utf8[0] = 0b11000000 | ((utf16be & 0x07C0) >> 6);
        utf8[1] = 0b10000000 | (utf16be & 0x003F);
        return 2;
    }
    utf8[0] = 0b11100000 | ((utf16be & 0xF000) >> 12);
    utf8[1] = 0b10000000 | ((utf16be & 0x0FC0) >> 6);
    utf8[2] = 0b10000000 | ((utf16be & 0x003F) >> 0);
    return 3;
}

/**
 * @brief 将 Hex 字符 c 转换为 int 加到 (*pval) 上
 * 
 * @param c 
 * @param pval 
 * @return int 
 */
int HexAddtoInt(char c, unsigned int *pval)
{
    if( isdigit(c) )
    {
        (*pval) = (*pval) * 0x10 + (c - '0');
    }
    else if(c >= 'a' && c <= 'f')
    {
        (*pval) = (*pval) * 0x10 + ( c - 'a' + 10);
    }
    else if( c >= 'A' && c <= 'F')
    {
        (*pval)  = (*pval) * 0x10 + ( c - 'A' + 10);
    }
    else
    {
        return -1;
    }
    return 0;
}

/**
 * @brief 将 Ocx 字符 c 转换为 int 加到 (*pval) 上
 * 
 * @param c 
 * @param pval 
 * @return int 
 */
int OcxAddtoInt(char c, unsigned int *pval)
{
    if(c >= '0' && c <= '7')
    {
        (*pval) = (*pval) * 010 + ( c - '0');
    }
    else
    {
        return -1;
    }
    return 0;
}

/**
 * @brief 将 Dec 字符 c 转换为 int 加到 (*pval) 上
 * 
 * @param c 
 * @param pval 
 * @return int 
 */
int DecAddtoInt(char c, unsigned int *pval)
{
    if(isdigit(c))
    {
        (*pval) = (*pval) * 10 + ( c - '0');
    }
    else
    {
        return -1;
    }
    return 0;
}

/**
 * @brief 根据 pstart、lpen两个数组提供的位置，读取文本并申请内存保存，然后置入 pstr，三个数组大小均要为 cnt
 * 
 * @param fp 
 * @param pstart 
 * @param plen 
 * @param pstr 
 * @param cnt 
 * @return int 
 */
int fstrdup(FILE*fp, const unsigned int pstart[], const unsigned int plen[], char* pstr[], int cnt)
{
    // long _posCur = ftell(fp); //保存当前位置
    // #ifndef NDEBUG
    // DebugPrintf("fstrdup:%c",' ');
    // for(int i = 0; i != cnt; i++)
    // {
    //     DebugPrintf("%u:%u ",pstart[i], plen[i]);
    // }
    // DebugPrintf("%c",'\n' );
    // #endif
    unsigned int _szMem = 0;
    for(int i = 0; i != cnt; i++)
    {
        if((int)pstart[i] != -1 && plen[i] > 0)
        {
            _szMem += plen[i] + 1;
        }
    }
    char* _pbuf = (char*)malloc(_szMem);
    if(_pbuf == NULL)
    {
        return -1;
    }
    int _cntNotNull = 0;
    for(int i = 0; i != cnt; i++)
    {
        if((int)pstart[i] != -1 && plen[i] > 0)
        {
            if(0 != fseek(fp, pstart[i],SEEK_SET))
            {
                pstr[i] = NULL;
                continue;
            }
            if(plen[i] != fread(_pbuf,1,plen[i], fp))
            {
                // fseek(fp, _posCur, SEEK_SET);
                return -1;
            }
            _pbuf[plen[i]] = 0;
            pstr[i] = _pbuf;
            _pbuf = _pbuf + (plen[i]+1);
            _cntNotNull ++;
        }
        else
        {
            pstr[i] = NULL;
        }
    }
    // fseek(fp, _posCur, SEEK_SET);
    // #ifndef NDEBUG
    // DebugPrintf("End of fstrdup:%c",' ');
    // for(int i = 0; i != cnt; i++)
    // {
    //     DebugPrintf("%u:%u|%s|",pstart[i], plen[i],(pstr[i]?pstr[i]:" "));
    // }
    // DebugPrintf("%c",'\n' );
    // #endif
    return _cntNotNull;
}

/**
 * @brief 检查 key 和 val 并调用函数转换后保存
 * 
 * @param fp 
 * @param sposKey 
 * @param lenKey 
 * @param sposVal 
 * @param lenVal 
 * @param pstr[2] 
 * @param fun_transform 
 * @return int 
 */
int fstrdup2(FILE*fp, const unsigned int sposKey, const unsigned int lenKey, 
                    const unsigned int sposVal, const unsigned int lenVal, char* pstr[2],
                    int (*fun_transform)(cfg_t*, char*,unsigned int),cfg_t*pcfg )
{
    // long _posCur = ftell(fp); //保存当前位置
    unsigned int _szMem = 0;
    if(sposKey != -1 && lenKey > 0)
    {
        _szMem += lenKey + 1;
    }
    if(sposVal != -1 && lenVal >0)
    {
        _szMem += lenVal + 1;
    }
    char* _pbuf = (char*)malloc(_szMem);
    if(_pbuf == NULL)
    {
        return -1;
    }
    if(sposKey != -1 && lenKey > 0)
    {
        if( !(0 ==fseek(fp, sposKey,SEEK_SET) && lenKey == fread(_pbuf,1,lenKey, fp)))
        {
            // fseek(fp, _posCur, SEEK_SET);
            pstr[0] = NULL;
            return -1;
        }
        pstr[0] = _pbuf;
        _pbuf = _pbuf + (lenKey + 1);
        pstr[0][lenKey] = 0;
    }
    if(sposVal != -1 && lenVal >0 )
    {
        if( !(0 ==fseek(fp, sposVal,SEEK_SET) && lenVal == fread(_pbuf,1,lenVal, fp)))
        {
            // fseek(fp, _posCur, SEEK_SET);
            pstr[1] = NULL;
            return -1;
        }
        pstr[1] = _pbuf;
        pstr[1][lenVal] = 0;
        int r = fun_transform(pcfg, pstr[1], lenVal);
        if( -1 == r )
        {
            return -1;
        }
        pstr[1][r] = 0;
    }
    return 0;
}

cfg_t* CfgMalloc(unsigned int cnt)
{
    unsigned int _szMem = CfgMemUsed(cnt);
    cfg_t* _pcfg = (cfg_t*)malloc(_szMem);
    if(_pcfg)
    {
        memset(_pcfg,0,_szMem);
        CfgInit(_pcfg,cnt);
    }
    return _pcfg;
}
cfg_t* CfgInit(cfg_t* pcfg, unsigned int cnt)
{
    pcfg->ptRoot =(tree_t *) ((char*)pcfg +  sizeof(cfg_t) );
    if(NULL == TreeInit(pcfg->ptRoot, sizeof(cfgdata_t), cnt))
    {
        return NULL;
    }
    struct cfgdata_t pcd = { 
        .type= CFG_TYPE_ROOT, 
    };
    TreeNodeSet(pcfg->ptRoot, TreeRoot(pcfg->ptRoot), &pcd);
    pcfg->signSaveComment = 1;
    return pcfg;
}
void CfgFree(cfg_t *pcfg)
{
    CfgUninit(pcfg);
    free(pcfg);
}

void CfgUninit(cfg_t *pcfg)
{
    CfgClose(pcfg);
    //遍历树，free 相关数据

    TreeUninit(pcfg->ptRoot);
}

int CfgOpen(const char * file, cfg_t *pcfg)
{
    FILE* fp = fopen(file,"rb+"); // 防止发生 \r 符号转换而导至 缓存位置和实际位置不对应
     /** @brief BOM 编号 
        0:EF BB BF	UTF-8;
        1:FE FF UTF16BE;
        2:FF FE UTF16LE;
        3:FF FE 00 00 UTF32LE;
        4:00 00 FE FF UTF32BE;
        255:no BOM
     */
    unsigned int _bom = 255;
    long _pos0 = 0; // 跳过BOM的ftell位置
    long _szFile = 0; //文件除了BOM之外的大小
    if( fp != NULL) 
    {
        // 分析BOM，跳过 BOM 字节
        // Bytes	Encoding Form
        // 00 00 FE FF	UTF-32BE, big-endian
        // FF FE 00 00	UTF-32LE, little-endian
        // FE FF	UTF-16BE, big-endian
        // FF FE	UTF-16LE, little-endian
        // EF BB BF	UTF-8
        struct _BOM{unsigned char* bom; unsigned char len;}BOM[] = { 
            {"\xEF\xBB\xBF",3,}, // utf-8
            {"\xFF\xFE",2, }, //UTF16LE
            {"\xFE\xFF",2, }, //UTF16BE
            {"\xFF\xFE\x00\x00",4,},//UTF32LE
            {"\x00\x00\xFE\xFF",4,} //UTF32BE
        };
        unsigned char _buf[4];
        size_t _len = fread(_buf,1,4, fp);
        switch (_len)
        {
        case 4:
            for(int i = 0; i != sizeof(BOM)/sizeof(BOM[0]); i++)
            {
                if(memcmp(BOM[i].bom, _buf, BOM[i].len) == 0 )
                {
                    _bom = i;
                    _pos0 = BOM[i].len;
                    break;
                }
            }
            break;
        case 3: //检查是否是utf8
            if(memcmp(BOM[0].bom, _buf,3) == 0 )
            {
                _bom = 0;
                _pos0 = 3;
            }
            break;
        case 2: //检查是否是UTF-16BE\ UTF-16LE
            if(memcmp(BOM[1].bom, _buf,2) == 0 )
            {
                _bom = 1;
            }
            else if(memcmp(BOM[2].bom, _buf,2) == 0 )
            {
                _bom = 2;
            }
            _pos0 = 2;
            break;
        default:
            if( ferror(fp) != 0 && feof(fp) != 0)
            {
                fclose(fp);
                fp = NULL;
                return -1;
            }
            break;
        }
        if(_pos0 < 4 && -1 == fseek(fp, _pos0, SEEK_SET))
        {
            fclose(fp);
            return -1;
        }
    }
    else
    {
        return -1;
    }
    // 初始化 cfg_t::pcpParse
    // 1. 检查共有多少字节的数据
    {
        fseek(fp,0,SEEK_END);
        size_t _posend = ftell(fp);
        fseek(fp,_pos0,SEEK_SET);
        _szFile = (long)_posend - _pos0;
    }
    // 2. 分配并初始化 cfg_t::parse
    {
        // 小于 MAX_PARSE_BUF 全部读取，大于 MAX_PARSE_BUF 读取 MAX_PARSE_BUF 数量
        unsigned int szBuf = _szFile < MAX_PARSE_BUF ? _szFile : MAX_PARSE_BUF;
        // // 经过查看JSON文本粗略估算一个文本的一个JSON语句平均约40~60字符，
        // // 此处预估一个JSON文本有 _szFile / 120 个语句，并向 1024/sizeof(cfgparsedata_t) 倍数取整
        // unsigned int szStack = roundup(_szFile / 120, 1024/sizeof(cfgparsedata_t) );
        unsigned int szStack = 32;
        pcfg->parse.pbuf = (char *)malloc( szBuf );
        if(NULL == pcfg->parse.pbuf)
        {
            return -1;
        }
        if(NULL == Stack2Init(&pcfg->parse.stackParseData, sizeof(cfgparsedata_t), szStack))
        {
            free(pcfg->parse.pbuf);
            return -1;
        }
        // if(NULL == TreeStackInit(&pcfg->parse.stackCfgData, szStack))
        // {
        //     free(pcfg->parse.pbuf);
        //     StackUninit(&pcfg->parse.stackParseData);
        //     return -1;
        // }
        // TreeStackPush(&pcfg->parse.stackCfgData, pcfg->ptRoot->pbtnRoot);
        // 初始化 pcfg->parse
        pcfg->parse.bom = _bom;
        pcfg->parse.szBom = _pos0;
        pcfg->parse.fp = fp;
        pcfg->parse.szPbuf = szBuf;
        pcfg->parse.szBuf = 0;
        pcfg->parse.posBuf = 0;
        pcfg->parse.line = 1; //行号从1开始
        pcfg->parse.pos = _pos0;
        // pcfg->parse.signReloadRead = 0;
    }
    return 0;
}

int CfgClose(cfg_t* pcfg)
{
    int _ret =  0;
    if(pcfg->parse.pbuf)
    {
        free(pcfg->parse.pbuf);
    }
    Stack2Uninit(&(pcfg)->parse.stackParseData);
    // TreeStackUninit(&(pcfg)->parse.stackCfgData);
    if(pcfg->parse.fp)
    {
        _ret = fclose(pcfg->parse.fp);//pcfg->parse.fp=NULL;
    }
    memset(&pcfg->parse,0, sizeof(cfgparse_t));
    return _ret;
}

// cfgiterator_t* CfgIteratorMalloc( cfg_t* pcfg)
// {
//     unsigned int _szMem = sizeof(cfgiterator_t);// + sizeof(treenode_t*) * 32;
//     cfgiterator_t* pcp = (cfgiterator_t*)malloc(sizeof(cfgiterator_t));
//     if(pcp == NULL || NULL == Stack2Init(&pcp->stack,sizeof(treenode_t*), 128))
//     {
//         if(pcp )
//         {
//             free(pcp);
//         }
//         return NULL;
//     }
//     pcp->pcfg = pcfg;
//     pcp->pcd = TreeRoot(pcfg->ptRoot);
//     Stack2Push(&pcp->stack,pcp->pcd); 
//     return pcp;
// }

// void CfgIteratorFree(cfgiterator_t* pcp)
// {
//     Stack2Uninit(&pcp->stack);
//     free(pcp);
// }

// cfgdata_t* CfgIteratorParent(cfgiterator_t* pcp)
// {
//     // assert(pcp->stack.cntElem);
//     // treenode_t * ptn;
//     // treenode_t * ptnt = pcp->pcd;
//     // while (ptn = Stack2Prev(&pcp->stack,ptnt))
//     // {
//     //     if(TreeNodeNext(ptn) != ptnt && TreeNodeChild(ptn) == ptnt)
//     //     {
//     //         pcp->pcd = ptn;
//     //         Stack2PopTo(&pcp->stack,ptnt);
//     //         return (cfgdata_t*)ptn->data;
//     //     }
//     // }
    
//     // if(ptn)
//     // {
//     //     return (cfgdata_t*)ptn->data;
//     // }
//     return NULL;
// }

// cfgdata_t* CfgIteratorChild(cfgiterator_t* pcp)
// {
//     assert(pcp->stack.cntElem);
//     // treenode_t * ptn = TreeNodeChild(pcp->pcd);
//     // if(ptn)
//     // {
//     //     pcp->pcd = ptn;
//     //     Stack2Push(&pcp->stack, ptn);
//     //     return (cfgdata_t*)ptn->data;
//     // }
//     return NULL;
// }

// cfgdata_t* CfgIteratorBrotherPrev(cfgiterator_t* pcp)
// {
//     assert(pcp->stack.cntElem);
//     // treenode_t * ptn = Stack2Prev(&pcp->stack, pcp->pcd);
//     // if(ptn && pcp->pcd == TreeGetBrother(ptn))
//     // {
//     //     Stack2Pop(&pcp->stack);
//     //     pcp->pcd = ptn;
//     //     return (cfgdata_t*)ptn->data;
//     // }
//     return NULL;
// }

// cfgdata_t* CfgIteratorBrotherNext(cfgiterator_t* pcp)
// {
//     assert(pcp->stack.cntElem);
//     // treenode_t * ptn = TreeGetBrother(pcp->pcd);
//     // if(ptn)
//     // {
//     //     if(NULL == Stack2Push(&pcp->stack, ptn))
//     //     {
//     //         return NULL;
//     //     }
//     //     return (cfgdata_t*)ptn->data;
//     // }
//     return NULL;
// }

// int CfgIteratorGetType(cfgiterator_t* pcp)
// {
//     return ((cfgdata_t*)pcp->pcd->data)->type;
// }

// int CfgIteratorIsRoot(cfgiterator_t* pcp)
// {
//     return (pcp->pcd == TreeRoot(pcp->pcfg->ptRoot));
// }

// int CfgIteratorIsStrs(cfgiterator_t* pcp)
// {
//     return ((((cfgdata_t*)pcp->pcd->data)->type & 0xFF00) == CFG_TYPE_STR);
// }

// int CfgIteratorIsInts(cfgiterator_t* pcp)
// {
//     return ((((cfgdata_t*)pcp->pcd->data)->type & 0xFF00) - CFG_TYPE_INT < 0x0F);
// }

// int CfgIteratorIsFloat(cfgiterator_t* pcp)
// {
//     return (((cfgdata_t*)pcp->pcd->data)->type == CFG_TYPE_FLOAT);
// }

// int CfgIteratorIsComplex(cfgiterator_t* pcp)
// {
//     return (((cfgdata_t*)pcp->pcd->data)->type == CFG_TYPE_COMPLEX);
// }

// char* CfgIteratorGetStr(cfgiterator_t* pcp)
// {
//     return ((((cfgdata_t*)pcp->pcd->data)->type & 0xFF00) == CFG_TYPE_STR) ? ((cfgdata_t*)pcp->pcd->data)->value.sval:NULL;
// }

// int CfgIteratorGetStrLen(cfgiterator_t* pcp)
// {
//     return ((((cfgdata_t*)pcp->pcd->data)->type & 0xFF00) == CFG_TYPE_STR) ? ((cfgdata_t*)pcp->pcd->data)->vlen:0;
// }

// long long CfgIteratorGetInt(cfgiterator_t* pcp)
// {
//     return (long long)(((cfgdata_t*)pcp->pcd->data)->value.llval);
// }

// unsigned long long CfgIteratorGetUint(cfgiterator_t* pcp)
// {
//     return (((cfgdata_t*)pcp->pcd->data)->value.llval);
// }
// double CfgIteratorGetFloat(cfgiterator_t* pcp)
// {
//     return (((cfgdata_t*)pcp->pcd->data)->value.fval);
// }

// float* CfgIteratorGetComplex(cfgiterator_t* pcp)
// {
//     return (float*)&(((cfgdata_t*)pcp->pcd->data)->value.cval);
// }

/**
 * @brief CfgParse 中调用的函数 跳过 \\x20 \\f \\t \\r \\n ，并计算行数，字符数，只认 \\n 为换行
 * 
 * @param pbuf 
 * @param sz 
 * @param pline 
 * @param ppos 
 * @return int 返回 0 表示，成功，返回 EOF_OF_BUF 表示分析到缓存结束位置了，需要继续读文本
 */
int _CfgParse_SkipSpace(cfg_t*pcfg)
{
    unsigned int _posBuf = pcfg->parse.posBuf;
    unsigned int _line = pcfg->parse.line;
    while (_posBuf < pcfg->parse.szBuf)
    {
        switch ( pcfg->parse.pbuf[_posBuf] )
        {
        case '\x20':case '\t': case '\f':case '\v':case '\r':
            _posBuf ++;
            continue; //
        case '\n':
            _line ++;
            _posBuf ++;
            continue;
        default:
            break;
        }
        break;
    }
    if(_posBuf < pcfg->parse.szBuf)
    {
        pcfg->parse.pos += (_posBuf - pcfg->parse.posBuf);
        pcfg->parse.posBuf = _posBuf;
        pcfg->parse.line = _line;
        return 0;
    }
    //读取到缓存结束，需要再次读取文本 返回1
    return EOF_OF_BUF;
}

/**
 * @brief 检查数字字符结束是否正确
 * 
 * @param pcfg 
 * @param posBuf 
 * @return int 
 */
int _CfgParse_GetNumberEnd(cfg_t* pcfg, unsigned int posBuf)
{
    char K[] = {' ','\t','\v','\f','\r','\n','\0',')','}',']',',',';', '/' };
    int _r = -1;
    for(int i = 0; i != sizeof(K)/sizeof(K[0]);i++)
    {
        if(pcfg->parse.pbuf[posBuf] == K[i])
        {
            _r = i;
            break;
        }
    }
    return _r; //跟了错误字符
}

/**
 * @brief 从 pBuf (*pPos)获取 整数 保存到 (* pValue) ，如果达到 maxBuf 返回 EOF_OF_BUF，正常返回 0
 * 
 * @param pBuf 
 * @param pPos 
 * @param maxBuf 
 * @param pValue 
 * @return int 
 */
int _CfgParse_GetNumber_GetInteger(char* pBuf, unsigned int *pPos,unsigned int maxBuf, unsigned long long* pValue)
{
    int p = (*pPos);
    while ((*pPos)<maxBuf)
    {
        if(isdigit(pBuf[(*pPos)]))
        {
            (*pValue) = (*pValue)*10 + (pBuf[(*pPos)] - '0');
            (*pPos)++;
            continue;
        }
        break;
    }
    if((*pPos)>=maxBuf)
    {
        return EOF_OF_BUF;
    }
    if(p == (*pPos)) // 表示在此没有获取任何数字
    {
        return -1;
    }
    return 0;
}

/**
 * @brief 获取小数部分
 * 
 * @param pBuf 
 * @param pPos 
 * @param maxBuf 
 * @param pValue 
 * @return int 
 */
int _CfgParse_GetNumber_GetDecimal(char* pBuf, unsigned int *pPos,unsigned int maxBuf, double* pValue)
{
    double cntDecimal = 1;
    while ((*pPos)<maxBuf)
    {
        if(isdigit(pBuf[(*pPos)]))
        {
            cntDecimal *= 0.1;
            (*pValue) += (pBuf[(*pPos)] - '0') * cntDecimal;
            (*pPos)++;
            continue;
        }
        break;
    }
    if((*pPos)>=maxBuf)
    {
        return EOF_OF_BUF;
    }
    return 0;
}

/**
 * @brief 跳过空格和Tab
 * 
 * @param pcfg 
 * @param pPosBuf 
 * @return int 
 */
int _CfgParse_GetNumber_SkipSpaceAndTab(cfg_t* pcfg, unsigned int* pPosBuf)
{
    while (pcfg->parse.pbuf[(*pPosBuf)] == ' ' || pcfg->parse.pbuf[(*pPosBuf)] == '\t') //允许 复数加号前有 空格或tab
    {
        (*pPosBuf)++;
    }
    if((*pPosBuf) >= pcfg->parse.szBuf)
    {
        return EOF_OF_BUF;
    }
    return 0;
}

/**
 * @brief 
 * 
 * @param pcfg 分析缓存中当前位置是不是数字 ,如果是，向 pcfg 中添加数据
 * @return int 
 */
int _CfgParse_GetNumber(cfg_t* pcfg, cfgparsedata_t* pcpd)
{
    if( !(isdigit(pcfg->parse.pbuf[pcfg->parse.posBuf]) || 
        pcfg->parse.pbuf[pcfg->parse.posBuf] == '+' || 
        pcfg->parse.pbuf[pcfg->parse.posBuf] == '-'))
    {
        return -2;
    }
    unsigned int _posBuf = pcfg->parse.posBuf;
    unsigned int _line = pcfg->parse.line;
    int _signNum = +1; // 数字的符号
    int _signDecimal = 0; //是否是小数
    int _signE = 0; //是否科学计数
    int _signComplex = 0; //是否复数。
    unsigned long long  _valueULL = 0; //无符号整数值
    double              _valueD = 0.0; // 双精度浮点数
    float               complex[2] = {0}; //复数
    _CfgParse_GetNumber_for_complex: //用于 complex再走一遍
    if(pcfg->parse.pbuf[_posBuf] == '-') //检查是不是 负号 '-'
    {
        _posBuf++;
        _signNum = -1;
        if(_posBuf >= pcfg->parse.szBuf)
        {
            return EOF_OF_BUF;
        }
    }
    else if(pcfg->parse.pbuf[_posBuf] == '+') // 检查是不是 正号 '+'
    {
        _signNum = +1;
        _posBuf++;
        if(_posBuf >= pcfg->parse.szBuf)
        {
            return EOF_OF_BUF;
        }
    }
    if(_CfgParse_GetNumber_SkipSpaceAndTab(pcfg, &_posBuf) == EOF_OF_BUF) //允许 符号和数字之间加空格或Tab
    {
        return EOF_OF_BUF;
    }
    if( (_signComplex == 0) && pcfg->parse.pbuf[_posBuf] == '0') //以 0 开头的数，可能是 十六进制整数/二进制整数/
    {
        _posBuf++;
        if(_posBuf >= pcfg->parse.szBuf)
        {
            return EOF_OF_BUF;
        }
        if(pcfg->parse.pbuf[_posBuf] == 'x' || pcfg->parse.pbuf[_posBuf] == 'X') //检查到十六进制
        {
            _posBuf++;
            if(_posBuf >= pcfg->parse.szBuf)
            {
                return EOF_OF_BUF;
            }
            while(_posBuf < pcfg->parse.szBuf)
            {
                int c = -1;
                if( isdigit(pcfg->parse.pbuf[_posBuf]))
                {
                    c = pcfg->parse.pbuf[_posBuf] - '0';
                }
                else if(pcfg->parse.pbuf[_posBuf] >= 'a' && pcfg->parse.pbuf[_posBuf] <= 'f')
                {
                    c = pcfg->parse.pbuf[_posBuf] - 'a'+ 10;
                }
                else if(pcfg->parse.pbuf[_posBuf] >= 'A' && pcfg->parse.pbuf[_posBuf] <= 'F')
                {
                    c = pcfg->parse.pbuf[_posBuf] - 'A' + 10;
                }
                else
                {
                    break;
                }
                _valueULL = _valueULL * 0x10 + c;
                _posBuf++;
            } //完成 十六进制的判断循环
            if(_posBuf < pcfg->parse.szBuf)
            {
                if(-1 != _CfgParse_GetNumberEnd(pcfg,_posBuf))
                {
                    // 语法错误
                    // to do
                    return -1;
                }
            }
            else
            {
                return EOF_OF_BUF;
            }
        }
        else if (pcfg->parse.pbuf[_posBuf] >= '0' || pcfg->parse.pbuf[_posBuf] <= '7') //检查到八进制
        {
            _posBuf++;
            if(_posBuf >= pcfg->parse.szBuf)
            {
                return EOF_OF_BUF;
            }
            while(_posBuf < pcfg->parse.szBuf)
            {
                if(pcfg->parse.pbuf[_posBuf] >= '0' && pcfg->parse.pbuf[_posBuf] <= '7')
                {
                    _valueULL = _valueULL * 0x10 + (pcfg->parse.pbuf[_posBuf] - '0');
                    _posBuf++;
                    continue;
                }
                break;
            } //完成 二进制的判断循环
            if(_posBuf < pcfg->parse.szBuf)
            {
                if(-1 != _CfgParse_GetNumberEnd(pcfg,_posBuf))
                {
                    // 语法错误
                    // to do
                    return -1;
                }
            }
            else
            {
                return EOF_OF_BUF;
            }
        }
        else if(pcfg->parse.pbuf[_posBuf] == 'b' || pcfg->parse.pbuf[_posBuf] == 'B') //检查到二进制
        {
            _posBuf++;
            if(_posBuf >= pcfg->parse.szBuf)
            {
                return EOF_OF_BUF;
            }
            while(_posBuf < pcfg->parse.szBuf)
            {
                if(pcfg->parse.pbuf[_posBuf] == '0' || pcfg->parse.pbuf[_posBuf] == '1')
                {
                    _valueULL = _valueULL * 0x10 + (pcfg->parse.pbuf[_posBuf] - '0');
                    _posBuf++;
                    continue;
                }
                break;
            } //完成 二进制的判断循环
            if(_posBuf < pcfg->parse.szBuf)
            {
                if(-1 != _CfgParse_GetNumberEnd(pcfg,_posBuf))
                {
                    // 语法错误
                    // to do
                    return -1;
                }
            }
            else
            {
                return EOF_OF_BUF;
            }
        }
    }
    else if(isdigit(pcfg->parse.pbuf[_posBuf])) //正常数字开头，可能是整数、小数、科学计数、复数
    {
        _valueULL = (pcfg->parse.pbuf[_posBuf] - '0');
        _posBuf++;
        int r = _CfgParse_GetNumber_GetInteger(pcfg->parse.pbuf, &_posBuf,pcfg->parse.szBuf,&_valueULL);
        if(r==-1) //语法错误 // to do
        {
            return -1;
        }
        else if(r == EOF_OF_BUF)
        {
            return EOF_OF_BUF;
        }
        if(pcfg->parse.pbuf[_posBuf] == '.')
        {
            _posBuf++;
            _signDecimal = 1;
            double valueDecimal = 0;
            int r  = _CfgParse_GetNumber_GetDecimal(pcfg->parse.pbuf, &_posBuf,pcfg->parse.szBuf,&valueDecimal);
            if(r == EOF_OF_BUF)
            {
                return EOF_OF_BUF;
            }
            _valueD = (double)( _signNum == -1 ? (-1 * (long long)_valueULL) : _valueULL) + valueDecimal;
        }
        if(pcfg->parse.pbuf[_posBuf] == 'e' || pcfg->parse.pbuf[_posBuf] == 'E') //处理科学计数
        {
            _posBuf++;
            if(_posBuf >= pcfg->parse.szBuf)
            {
                return EOF_OF_BUF;
            }
            _signE = +1; 
            unsigned long long valueE = 0;
            if(pcfg->parse.pbuf[_posBuf] == '-')
            {
                _signE = -1;
                _posBuf++;
            }
            else if(pcfg->parse.pbuf[_posBuf] == '+')
            {
                _posBuf++;
            }
            int r = _CfgParse_GetNumber_GetInteger(pcfg->parse.pbuf, &_posBuf,pcfg->parse.szBuf,&valueE);
            if(r == EOF_OF_BUF)
            {
                return EOF_OF_BUF;
            }
            else if( r== -1) //没有获取 E后面的数字，语法错误
            {
                // to do
                return -1;
            }
            _valueD = (_signDecimal? _valueD : (_signNum*(long long)_valueULL)) * pow(_signE==-1?0.1:10,valueE);
            _signDecimal = 1; //视科学计学为浮点数
        }
        if(_signComplex == 0) // 处理复数，_signComplex 配合 goto _CfgParse_GetNumber_for_complex 处理 复数
        {
            if(_CfgParse_GetNumber_SkipSpaceAndTab(pcfg, &_posBuf) == EOF_OF_BUF) //允许 符号和数字之间加空格或Tab
            {
                return EOF_OF_BUF;
            }
            if(pcfg->parse.pbuf[_posBuf] == '+') //处理复数
            {
                _signComplex = 1;
                _posBuf++;
                if(_CfgParse_GetNumber_SkipSpaceAndTab(pcfg, &_posBuf) == EOF_OF_BUF) //允许 符号和数字之间加空格或Tab
                {
                    return EOF_OF_BUF;
                }
                if(pcfg->parse.pbuf[_posBuf] == 'i') // 查看是否是i,如果不是i就报语法错误
                {
                    _posBuf++;
                    complex[0] = (float)_signNum * (float)(_signDecimal ? _valueD : _valueULL);
                    _signNum = +1; // 数字的符号
                    _signDecimal = 0; //是否是小数
                    _signE = 0; //是否科学计数
                    _valueULL = 0; //无符号整数值
                    _valueD = 0.0; // 双精度浮点数
                    goto _CfgParse_GetNumber_for_complex; //再执行一遍
                }
                else
                {
                    //语法错误 复数语法错误
                    return -1;
                }
            }
        }
        else
        {
            complex[1] = (float)_signNum * (float)(_signDecimal ? _valueD : _valueULL);
            _signDecimal = 0; //是否是小数
            _signE = 0; //是否科学计数
        }
    }
    if(_posBuf >= pcfg->parse.szBuf) //要求缓存中必须有一个不属于数字的字符
    {
        return EOF_OF_BUF;
    }
    cfgdata_t cd = {0}; //需要存入数的值
    int markPop = 0; // 是否需要弹出栈数据
    treenode_t * parentNode=NULL;
    cfgparsedata_t *ppcpd = NULL;
    if(pcpd)
    {
        if(pcpd->type == CFG_TYPE_NULL || (pcpd->type & 0xFF00) == CFG_TYPE_INT )
        {//如果 pcfg->parse.stackParseData 栈中是整型或无类型，处理之
            // 检查合法性
            ppcpd = Stack2Prev(&pcfg->parse.stackParseData, pcpd);
            if( !(ppcpd == NULL  || 
                (((ppcpd->type&0xFFF0) == CFG_TYPE_GROUP && pcpd->sposKey != -1) || 
                ((ppcpd->type&0xFFF0) == CFG_TYPE_ARRAY && pcpd->sposKey == -1) ) ) )
            {
                // 当前上级是root/当前是键值对上级是 group/map / 当前是值上级是 array/set,正确，不然错误,语法错误
                return -1;
            }
            cd.type = pcpd->type; 
            if(-1 == fstrdup(pcfg->parse.fp, &pcpd->sposKey, &pcpd->lenKey, &cd.key,1)) //未测试
            {
                return -1;
            }
            markPop = 1;
            parentNode = pcpd->parentNode;
        }
        else if((pcpd->type&0xFFF0) == CFG_TYPE_ARRAY)
        {
            parentNode = pcpd->selfNode;
        }
        else // 其它类型也为错误
        {
            //语法错误
            return -1;
        }
    }
    else 
    {
        parentNode = TreeRoot(pcfg->ptRoot);
    }
    if(cd.type == CFG_TYPE_NULL) //没有限定类型，需要根据数据猜类型
    {
        if(_signDecimal) // 小数
        {
            cd.type = CFG_TYPE_FLOAT;
            cd.value.fval = _valueD;DebugPrintf("Find:float:%lf\n",cd.value.fval );
        }else if(_signComplex) // 复数
        {
            cd.type = CFG_TYPE_COMPLEX;
            cd.value.cval.real = complex[0];
            cd.value.cval.imag = complex[1];DebugPrintf("Find:complex:%f+i%f\n",cd.value.cval.real, cd.value.cval.imag);
        }
        else //整数
        {
            cd.type = CFG_TYPE_INT;
            cd.value.llval = (long long)(_valueULL);DebugPrintf("Find:uint:%lld\n",(long long)cd.value.llval );
        }
    }
    else //已知类型，转换相关的数据到对应类型
    {
        if(_signDecimal && cd.type != CFG_TYPE_FLOAT) //如果是小数, 但是要求的类型 不是小数
        {
            if(cd.type < CFG_TYPE_FLOAT)
            {
                _valueULL = _valueD >=0 ? (unsigned long long)_valueD : (long long)_valueD;
            }
            else if(cd.type == CFG_TYPE_COMPLEX)
            {
                complex[0] = ((long long)_valueD);complex[1]=0;
            }
        }
        else if(_signComplex && cd.type != CFG_TYPE_COMPLEX) // 如果是复数
        {
            if(cd.type < CFG_TYPE_FLOAT)
            {
                _valueULL = complex[0] >=0 ? complex[0] : complex[0];
            }
            else if(cd.type == CFG_TYPE_FLOAT)
            {
               _valueD = (complex[0]);
            }
        }
        else if((cd.type & 0xFF00)== CFG_TYPE_INT16)//是整数
        {
            if(cd.type == CFG_TYPE_FLOAT)
            {
               _valueD = ((long long)_valueULL);
            }
            else if(cd.type == CFG_TYPE_COMPLEX)
            {
                complex[0] = ((long long)_valueULL);complex[1]=0;
            }
        }
        switch (cd.type)
        {
        case CFG_TYPE_FLOAT: 
            cd.value.fval = _valueD;DebugPrintf("Find:float:%lf\n",cd.value.fval );
            break;
        case CFG_TYPE_INT:
            cd.value.llval = (long long)(_valueULL);DebugPrintf("Find:int:%lld\n",(long long)cd.value.llval );
            break;
        case CFG_TYPE_UINT:
            cd.value.llval = (long long)(unsigned long long)(_valueULL);DebugPrintf("Find:uint:%llu\n",cd.value.llval );
            break;
        case CFG_TYPE_INT8:
            cd.value.llval = (long long)(char)(_valueULL);DebugPrintf("Find:int8:%hhd\n",(char)cd.value.llval );
            break;
        case CFG_TYPE_UINT8:
            cd.value.llval = (long long)(unsigned char)(_valueULL);DebugPrintf("Find:uint8:%hhu\n",(unsigned char)cd.value.llval );
            break;
        case CFG_TYPE_INT16:
            cd.value.llval = (long long)(short)(_valueULL);DebugPrintf("Find:int16:%hd\n",(short)cd.value.llval );
            break;
        case CFG_TYPE_UINT16:
            cd.value.llval = (long long)(unsigned short)(_valueULL);DebugPrintf("Find:uint16:%hu\n",(unsigned short)cd.value.llval );
            break;
        case CFG_TYPE_INT32:
            cd.value.llval = (long long)(int)(_valueULL);DebugPrintf("Find:int32:%d\n",(int)cd.value.llval );
            break;
        case CFG_TYPE_UINT32:
            cd.value.llval = (long long)(unsigned int)(_valueULL);DebugPrintf("Find:uint32:%u\n",(unsigned int)cd.value.llval );
            break;
        case CFG_TYPE_BOOL:
            cd.value.llval = !!(unsigned long long)(_valueULL);DebugPrintf("Find:bool:%s\n",(cd.value.llval == 0? "false":"true") );
            break;
        case CFG_TYPE_COMPLEX:
            cd.value.cval.real = complex[0];
            cd.value.cval.imag = complex[1]; DebugPrintf("Find:complex:%f+i%f\n",cd.value.cval.real, cd.value.cval.imag);
            break;
        }
    }
    pcfg->parse.pos += (_posBuf - pcfg->parse.posBuf);
    pcfg->parse.posBuf = _posBuf;
    //准备 将此数据插入 cfg_t::ptRoot 树中
    if(NULL ==  TreeNodeAddChild2(pcfg->ptRoot, parentNode, &cd))
    {
        if(cd.key){free(cd.key);}
        return -1;
    }
    ((cfgdata_t*) (pcpd->parentNode->data))->value.llval ++; // 容器子元素数量加1
    if(markPop)
    {
        Stack2Pop(&pcfg->parse.stackParseData);
    }
    return 0;
}

/**
 * @brief 由 str/estr/number 等调用，检查 pcpd 或 ppcpd 是否是合法的 group/array/array/
 * 
 * @param pcfg 
 * @param pcpd 
 * @return int 
 */
int _CfgParse_CheckContainer(cfg_t* pcfg, cfgparsedata_t* pcpd)
{
    return 0;
}

/**
 * @brief 检查 键值对 如果第一个字符不是 '{' 返回 -2
 * 
 * @param pcfg 
 * @param pcpd 
 * @return int 
 */
int _CfgParse_GetGroup(cfg_t* pcfg, cfgparsedata_t* pcpd)
{
    int _markReadKey = 0; // 标记是否读取 key 名
    // 已经检查过有没有空白字符
    if(pcfg->parse.pbuf[pcfg->parse.posBuf] != '{')
    {
        if(pcpd && (pcpd->type ==CFG_TYPE_GROUP && pcpd->stage == CFG_PARSE_STAGE_COLON))
        {
            //已经使用 group:约定为 group 但是不是跟 '{' ,语法错误
            pcfg->diagnosis.err = CFG_ERR_GROUP_NOT_LBRACES;
            pcfg->diagnosis.line = pcfg->parse.line;
            pcfg->diagnosis.pos = pcfg->parse.pos;
            return -1;
        }
        return -2;
    }
    // else 
    // {
    //     if(!(pcpd == NULL || // pcpd 为空时说明上级是 root
    //         ( (pcpd->type ==CFG_TYPE_GROUP && pcpd->stage == CFG_PARSE_STAGE_COLON) || // 读取到了 group:{ 这样的字符
    //           ( CfgTypeIsVContainer(pcpd->type) && (pcpd->stage & 0xFFF0) == CFG_PARSE_STAGE_ARRAY ) ||//上级是 array 或 set 容器，并且正在读元素
    //           (pcpd->type == CFG_TYPE_NULL && pcpd->stage == CFG_PARSE_STAGE_KEYVALUE_EQL) ) ) ) // 读取取 var_name={ 这样的类似字符
    //     {
    //         //当不是以上几种情况时，语法错误
    //         pcfg->diagnosis.err = CFG_ERR_GROUP_NOT_LBRACES;
    //         pcfg->diagnosis.line = pcfg->parse.line;
    //         pcfg->diagnosis.pos = pcfg->parse.pos;
    //         // to do
    //         return -1;
    //     }
    // }
    DebugPrintf("Find:group,Pos:%u \n",pcfg->parse.posBuf);
    pcfg->parse.posBuf++;
    pcfg->parse.pos++;
    int markNewGroup = 0;
    treenode_t* parentNode = NULL;
    if(pcpd)
    {
        if(pcpd->type ==CFG_TYPE_GROUP)
        {
            pcpd->stage = CFG_PARSE_STAGE_GROUP;
            assert(pcpd->parentNode != NULL);
            parentNode = pcpd->parentNode;
            if(pcpd->sposKey != -1)
            {
                _markReadKey = 1;
            }
        }
        else if(pcpd->type == CFG_TYPE_NULL)
        {
            pcpd->type =CFG_TYPE_GROUP;
            pcpd->stage = CFG_PARSE_STAGE_GROUP;
            assert(pcpd->parentNode != NULL);
            parentNode = pcpd->parentNode;
            _markReadKey = 1;
        }
        else
        {
            markNewGroup=1;
            assert(CfgTypeIsVContainer(pcpd->type) && pcpd->selfNode != NULL); //此处上级是 array/set空器，所以必须有 selfNode值
            parentNode = pcpd->selfNode;
        }
    }
    else
    {
        markNewGroup=1;
        parentNode = TreeRoot(pcfg->ptRoot);
    }
    cfgdata_t cd = { .type = CFG_TYPE_GROUP, };
    if(_markReadKey && -1 == fstrdup(pcfg->parse.fp, &pcpd->sposKey, &pcpd->lenKey,&cd.key,1))
    {
        //分配内存出错，系统错误
        pcfg->diagnosis.err = CFG_ERR_MALLOC_KEY;
        pcfg->diagnosis.line = pcfg->parse.line;
        pcfg->diagnosis.pos = pcfg->parse.pos;
        return -1;
    }
    treenode_t* node = TreeNodeAddChild2(pcfg->ptRoot, parentNode,&cd); // 新的树结点
    if(node == NULL)
    {
        // 无法插入tree，系统错误
        pcfg->diagnosis.err = CFG_ERR_ADD_TREE_LEAF;
        pcfg->diagnosis.line = pcfg->parse.line;
        pcfg->diagnosis.pos = pcfg->parse.pos;
        if(cd.key){free(cd.key);}
        return -1;
    }
    ((cfgdata_t*) (pcpd->parentNode->data))->value.llval ++; // 容器子元素数量加1
    if(markNewGroup == 1)
    {
        cfgparsedata_t cpd = {
            .type = CFG_TYPE_GROUP,.stage = CFG_PARSE_STAGE_GROUP, .parentNode = parentNode, .selfNode = node
        };
        if(NULL == Stack2Push(&pcfg->parse.stackParseData, &cpd))
        {
            pcfg->diagnosis.err = CFG_ERR_ADD_STACK;
            pcfg->diagnosis.line = pcfg->parse.line;
            pcfg->diagnosis.pos = pcfg->parse.pos;
            return -1;
        }
    }
    else
    {
        pcpd->selfNode = node;
    }
    return 0;
}

/**
 * @brief 检查 键值对 如果第一个字符不是 '(' 返回 -2
 * 
 * @param pcfg 
 * @param pcpd 
 * @return int 
 */
int _CfgParse_GetArray(cfg_t* pcfg, cfgparsedata_t* pcpd)
{
    // 已经检查过有没有空白字符
    if(pcfg->parse.pbuf[pcfg->parse.posBuf] != '[')
    {
        if(pcpd && (pcpd->type ==CFG_TYPE_ARRAY && pcpd->stage == CFG_PARSE_STAGE_COLON))
        {
            //已经使用 group:约定为 group 但是不是跟 '[' ,语法错误
            pcfg->diagnosis.err = CFG_ERR_ARRAY_NOT_BRACKETS;
            pcfg->diagnosis.line = pcfg->parse.line;
            pcfg->diagnosis.pos = pcfg->parse.pos;
            return -1;
        }
        return -2;
    }
    // else 
    // {
    //     if(!(pcpd == NULL || // pcpd 为空时说明上级是 root
    //         ( ((pcpd->type &0xFFF0)== CFG_TYPE_GROUP && (pcpd->stage & 0xFFF0) == CFG_PARSE_STAGE_GROUP ) ||//上级是 group 或 map 容器，并且正在读元素
    //           (pcpd->type == CFG_TYPE_NULL && pcpd->stage == CFG_PARSE_STAGE_KEYVALUE_EQL) || // 读取取 var_name={ 这样的类似字符
    //           (pcpd->type ==CFG_TYPE_ARRAY && pcpd->stage == CFG_PARSE_STAGE_COLON) ) ) )// 读取到了 array:{ 这样的字符
    //     {
    //         //当不是以上几种情况时，语法错误
    //         // to do
    //         return -1;
    //     }
    // }
    DebugPrintf("Find:array,Pos:%u \n",pcfg->parse.posBuf);
    pcfg->parse.posBuf++;
    pcfg->parse.pos++;
    int markNewGroup = 0;
    treenode_t* parentNode = NULL;
    if(pcpd)
    {
        if(pcpd->type ==CFG_TYPE_ARRAY) // 应对 array:[ 
        {
            pcpd->stage = CFG_PARSE_STAGE_ARRAY;
            assert(pcpd->parentNode != NULL);
            parentNode = pcpd->parentNode;
        }
        else if(pcpd->type == CFG_TYPE_NULL) // 应对 var = [
        {
            pcpd->type =CFG_TYPE_ARRAY;
            pcpd->stage = CFG_PARSE_STAGE_ARRAY;
            assert(pcpd->parentNode != NULL);
            parentNode = pcpd->parentNode;
        }
        else
        {
            markNewGroup=1;
            assert(pcpd->selfNode != NULL); //此处上级是 array/set空器，所以必须有 selfNode值
            parentNode = pcpd->selfNode;
        }
    }
    else
    {
        markNewGroup=1;
        parentNode = TreeRoot(pcfg->ptRoot);
    }
    cfgdata_t cd = { .type = CFG_TYPE_ARRAY, };
    if(-1 == fstrdup(pcfg->parse.fp, &pcpd->sposKey, &pcpd->lenKey,&cd.key,1))
    {
        //分配内存出错，系统错误
        return -1;
    }
    treenode_t* node = TreeNodeAddChild2(pcfg->ptRoot, parentNode,&cd); // 新的树结点
    if(node == NULL)
    {
        // 无法插入tree，系统错误
        if(cd.key){free(cd.key);}
        return -1;
    }
    ((cfgdata_t*) (pcpd->parentNode->data))->value.llval ++; // 容器子元素数量加1
    if(markNewGroup == 1)
    {
        cfgparsedata_t cpd = {
            .type = CFG_TYPE_ARRAY,.stage = CFG_PARSE_STAGE_ARRAY, .parentNode = parentNode, .selfNode = node
        };
        if(NULL == Stack2Push(&pcfg->parse.stackParseData, &cpd))
        {
            return -1;
        }
    }
    else
    {
        pcpd->selfNode = node;
    }
    return 0;
}

/**
 * @brief 获取当前 分析时的 父元素
 * 
 * @param pcfg 
 * @param pcpd 
 * @return treenode_t* 
 */
treenode_t* _GetParentNodebypcpd(cfg_t* pcfg, cfgparsedata_t* pcpd)
{
    treenode_t* _parentNode = NULL; // 父元素
    cfgparsedata_t *_ppcpd = pcpd?Stack2Prev(&pcfg->parse.stackParseData, pcpd):NULL;
    if(pcpd)
    {
        if(CfgTypeIsContainer(pcpd->type)) //当前 cfgparsedata_t 是容器
        {
            _parentNode = pcpd->selfNode;
        }
        else 
        { //不是容器
            _parentNode = pcpd->parentNode;
        }
    }
    else
    {
        _parentNode = TreeRoot(pcfg->ptRoot);
    }
    return _parentNode;
}

/**
 * @brief 扫描字符串另一个分隔符
 * 
 * @param pcfg 
 * @param pPosBuf 
 * @param markSeparator 
 * @return int 
 */
int _CfgParse_GetStr_ScanSeparator(cfg_t* pcfg, unsigned int*pPosBuf, int markSeparator)
{
    while ((*pPosBuf) < pcfg->parse.szBuf && pcfg->parse.pbuf[(*pPosBuf)] != markSeparator)
    {
        if(pcfg->parse.pbuf[(*pPosBuf)] == '\n')
        {
            // 语法错误，禁止多行字符串
            pcfg->diagnosis.err = CFG_ERR_STR_HAS_LF;
            pcfg->diagnosis.line = pcfg->parse.line;
            pcfg->diagnosis.pos = pcfg->parse.pos + ((*pPosBuf) - pcfg->parse.posBuf);
            return -1;
        }
        (*pPosBuf)++;
    }
    return 0;
}

/**
 * @brief 分析字符串，字符串可能在 root下，也可能在 group/map下作为 key
 * 
 * @param pcfg 
 * @param pcpd 
 * @return int 
 */
int _CfgParse_GetStr(cfg_t* pcfg, cfgparsedata_t* pcpd)
{
    unsigned int _posBuf; //当前缓存分析位置
    int _markSeparator = -1;// 分隔符，可能是 '\'' 或 '"'
    // 1. 检查 pcpd 是否是正在分析字符串，防止字符串跨跃一个以上的缓存
    if(pcpd)
    {
        _posBuf = pcfg->parse.posBuf; // 
        // 以下是检查 pcpd 以处理字符串跨跃缓存的情况 （不在一个缓存中，被分成两部分读取）
        if(pcpd->stage == CFG_PARSE_STAGE_STR)
        {
            _markSeparator = (int)pcpd->value.llval;
            // 继续查找 分隔符，可能是 '\'' 或 '"'
            if(_CfgParse_GetStr_ScanSeparator(pcfg,&_posBuf,_markSeparator) == -1)
            {
                return -1;
            }
            if(_posBuf >= pcfg->parse.szBuf) // 字符串继续跨越了缓存，
            {
                pcfg->parse.pos += _posBuf - pcfg->parse.posBuf;
                pcfg->parse.posBuf = _posBuf;
                return EOF_OF_BUF;
            }
            goto _CfgParse_GetStr_AddtoTree;
        }
    }
    if(_markSeparator == -1 && (!(pcfg->parse.pbuf[pcfg->parse.posBuf] == '\'' || pcfg->parse.pbuf[pcfg->parse.posBuf] == '"'))) //不是字符串
    {
        return -2; 
    }
    _markSeparator = pcfg->parse.pbuf[pcfg->parse.posBuf]; //记录 字符串的分隔符
    pcfg->parse.pos++;pcfg->parse.posBuf++; // 跳过分隔符
    _posBuf = pcfg->parse.posBuf;
    // 扫描查找 字符串分隔符 可能是 '\'' 或 '"'
    if(_CfgParse_GetStr_ScanSeparator(pcfg,&_posBuf,_markSeparator) == -1)
    {
        return -1;
    }
    if(_posBuf >= pcfg->parse.szBuf) // 到缓存结束仍然没有发现 分隔符 可能是 '\'' 或 '"'， 字符串跨越了缓存，处理跨越缓存的情况
    {
        int markAddtoStack = 1; //标记加到栈之中
        if(pcpd)
        {
            if(pcpd->type == CFG_TYPE_STR) // 是 group/map/root 中的键值对的值 并且值带有 str:
            {
                pcpd->stage = CFG_PARSE_STAGE_STR;
                markAddtoStack = 0;
            }
            else if(pcpd->type == CFG_TYPE_NULL) // 是 group/map/root 中的键值对的值 并且值没有带 str:
            {
                pcpd->type = CFG_TYPE_STR;
                pcpd->stage = CFG_PARSE_STAGE_STR;
                markAddtoStack = 0;
            }
        }
        if(markAddtoStack)
        {
            cfgparsedata_t cpd = {
                .type = CFG_TYPE_STR,.stage=CFG_PARSE_STAGE_STR,
                .sposKey = -1,.lenKey = 0, .sposVal = pcfg->parse.pos, .lenVal = _posBuf - pcfg->parse.posBuf,
                .parentNode = _GetParentNodebypcpd(pcfg,pcpd),
            };
            if(NULL == Stack2Push(&pcfg->parse.stackParseData, &cpd))
            {
                return -1;
            }
        }
        else
        {
            pcpd->lenVal += _posBuf - pcfg->parse.posBuf;
        }
        pcfg->parse.pos += _posBuf - pcfg->parse.posBuf;
        pcfg->parse.posBuf = _posBuf;
        return EOF_OF_BUF;
    }
    // 已检查到字符串结束
    
    if(pcpd)
    {
        cfgparsedata_t *ppcpd = NULL;
        if( CfgTypeIsKVContainer(pcpd->type) )
        {//父元素是 容器，先检查到 字符串，视为 键值对的 key
            cfgparsedata_t cpd = {
                .type = CFG_TYPE_NULL,.stage=CFG_PARSE_STAGE_KEYVALUE_KEY,
                .sposKey = pcfg->parse.pos,.lenKey =  _posBuf - pcfg->parse.posBuf, .sposVal = -1, .lenVal = 0,
                .parentNode = _GetParentNodebypcpd(pcfg,pcpd),
            };
            if(NULL == Stack2Push(&pcfg->parse.stackParseData, &cpd))
            {
                pcfg->diagnosis.err = CFG_ERR_ADD_STACK;
                pcfg->diagnosis.line = pcfg->parse.line;
                pcfg->diagnosis.pos = pcfg->parse.pos + (_posBuf - pcfg->parse.posBuf);
                return -1;
            }
            pcfg->parse.pos += (_posBuf - pcfg->parse.posBuf + 1); //加一是去掉字符串尾部的 分隔符
            pcfg->parse.posBuf = (_posBuf + 1);
            return 0;
        }
        else if ( ( pcpd->type == CFG_TYPE_STR && pcpd->sposKey == -1 && 
                (ppcpd = Stack2Prev(&pcfg->parse.stackParseData, pcpd)) && 
                (ppcpd->type == CFG_TYPE_GROUP ) )) // 本身没有key值，父元素为 gruop或map,视为变量
        {
            pcpd->type = CFG_TYPE_NULL; pcpd->stage=CFG_PARSE_STAGE_KEYVALUE_KEY; 
            pcpd->sposKey = pcpd->sposVal; pcpd->lenKey = pcpd->lenVal + _posBuf - pcfg->parse.posBuf;
            pcpd->sposVal = -1; pcpd->lenVal = 0;
            pcfg->parse.pos += (_posBuf - pcfg->parse.posBuf + 1); //加一是去掉字符串尾部的 分隔符
            pcfg->parse.posBuf = (_posBuf + 1);
            return 0;
        }        
    }
    else
    {
        //父元素 为 root 先加到 stack 中，防止后面是 , 或 ;
            cfgparsedata_t cpd = {
                .type = CFG_TYPE_STR, .stage=CFG_PARSE_STAGE_KEYVALUE_KEY,
                .sposKey = pcfg->parse.pos,.lenKey =  _posBuf - pcfg->parse.posBuf, .sposVal = -1, .lenVal = 0,
                .parentNode = _GetParentNodebypcpd(pcfg,pcpd),
            };
            if(NULL == Stack2Push(&pcfg->parse.stackParseData, &cpd))
            {
                pcfg->diagnosis.err = CFG_ERR_ADD_STACK;
                pcfg->diagnosis.line = pcfg->parse.line;
                pcfg->diagnosis.pos = pcfg->parse.pos + (_posBuf - pcfg->parse.posBuf);
                return -1;
            }
            pcfg->parse.pos += (_posBuf - pcfg->parse.posBuf + 1); //加一是去掉字符串尾部的 分隔符
            pcfg->parse.posBuf = (_posBuf + 1);
            return 0;
    }
    _CfgParse_GetStr_AddtoTree:
    char* pstr[2] = {0};
    unsigned int ppos[2] = {-1,-1};
    unsigned int plen[2] = {0};
    if(pcpd)
    {
        if(pcpd->stage == CFG_PARSE_STAGE_STR) //字符串分部在大于等于两个缓存之中
        {
            ppos[1] = pcpd->sposVal; plen[1] = _posBuf - pcpd->sposVal;
        }
        else
        {
            ppos[1] = pcfg->parse.pos; plen[1] = _posBuf - pcfg->parse.posBuf;
        }
        if((pcpd->type == CFG_TYPE_NULL || pcpd->type == CFG_TYPE_STR ) )
        {
            ppos[0] = pcpd->sposKey; plen[0] =pcpd->lenKey;
            Stack2Pop(&pcfg->parse.stackParseData);
        }
    }
    if(-1 == fstrdup(pcfg->parse.fp, ppos, plen, pstr,2)) 
    {
        return -1;
    }
    DebugPrintf("Find:string:%s=%s \n" ,(pstr[0]!=NULL?pstr[0]:" "), pstr[1]);
    // 将数据加入树
    cfgdata_t cd = {
        .type = CFG_TYPE_STR,
        .key = pstr[0],
        .klen = plen[0],
        .value.sval = pstr[1],
        .vlen = plen[1],
    };
    treenode_t *parentNode = _GetParentNodebypcpd(pcfg,pcpd);
    if(NULL == TreeNodeAddChild2(pcfg->ptRoot,parentNode,&cd))
    {
        if(cd.key){free(cd.key);}
        return -1;
    }
    ((cfgdata_t*) (parentNode))->value.llval ++; // 容器子元素数量加1
    pcfg->parse.pos += (_posBuf - pcfg->parse.posBuf + 1); //加一是去掉字符串尾部的 分隔符
    pcfg->parse.posBuf = (_posBuf + 1);
    return 0;
}

// 用于 estr检查 ， 需要检查的字符串
char ESTR_CHs[][2] ={{'n','\n'},{'t','\t'},{'r','\r'},{'\\','\\'},{'\"','\"'},{'\'','\''},
                    {'\?','\?'},{'a','\a'}, {'b','\b'},{'f','\f'},{'v','\v'},{'`','`'},// 前面有12个
                    {'x','x'},{'u','u'},{'0',0},{'1',1},{'2',2},{'3',3},
                    {'4',4},{'5',5},{'6',6},{'7',7},{'\n','\n'},{'\r','\r'}, /* 后面也有12个 */}; 
/**
 * @brief 处理 转义字符串
 * 
 * @param pcfg 
 * @param pcpd 
 * @param sign 
 * @param pPosBuf 
 * @param pCntStr 保存转义之后字符数量
 * @param bufDst 保存转义之后的字符，如果为 NULL 跳过
 * @return int 
 */

/**
 * @brief 根据 buf 来处理转义字符，并放在 buf 之中，返回处理之后字符数量
 * 
 * @param pcfg 
 * @param buf 
 * @param cnt 传入的 buf 大小
 * @return int 返回处理之扣的字符数量 单位：字节
 */
int _CfgParse_GetEstr_Parse(cfg_t* pcfg, char* buf,unsigned int cnt)
{
    // 转义字符 	含义 	ASCII 码值（十进制/十六进制） 	详细解释
    // \a 	警报（响铃 7/7 	发出系统提示音，通常用于引起用户注意。在某些系统中可能没有明显效果。
    // \b 	退格 	8/8 	将光标位置向左移动一个字符。如果光标已经在行首，则行为可能因系统而异。
    // \f 	换页 	12/c 	将光标移动到下一页的开头。在打印输出时很有用，但在屏幕输出中可能显示为空白字符。
    // \n 	换行 	10/a 	将光标移动到下一行的开头。这是最常用的行结束符，用于文本的换行。
    // \r 	回车 	13/d 	将光标移动到当前行的开头。通常与 \n 配合使用，在 Windows 系统中表示换行。
    // \t 	水平制表符 	9/9 	将光标移动到下一个制表位置。通常用于对齐文本或创建缩进效果。
    // \v 	垂直制表符 	11/b 	在支持的设备上，将光标向下移动到下一个垂直制表位置。在大多数现代终端中，效果可能与 \n 相同。
    // \\ 	反斜杠 	92/5C 	用于在字符串中表示一个字面意义上的反斜杠字符。
    // \' 	单引号 	39/27 	用于在字符常量中表示一个字面意义上的单引号字符。
    // \" 	双引号 	34/22 	用于在字符串常量中表示一个字面意义上的双引号字符。
    // \? 	问号 	63/3F 	用于表示字面意义上的问号，主要用于避免触发三字符序列。
    // \0 	空字符（NULL） 	0/0 	表示字符串的结束。在 C 语言中，字符串以空字符结尾。
    // \xhh 	十六进制值 	- 	表示一个十六进制值，其中 hh 是一个或多个十六进制数字。例如，\x41 表示字符 'A'。
                            // 注意：gcc如果\x后跟很长一串，只看最后两位十六进制，但msvc报Err:2022
    // \ooo 	八进制值 	- 	表示一个八进制值，其中 ooo 是一到三个八进制数字。例如，\101 表示字符 'A'。
    // \uhhhh utf16BE编码，把 bbbb bbbb  bbbb bbbb 的utf16BE 按顺序映射到 1110xxxx 	10xxxxxx 	10xxxxxx 的utf8编码
    // 继续查找 分隔符, 可能是 '\'' 或 '"'或 '`', 要求分隔符前不能有转义字符
    // int _markSeparator = pcpd->value.llval;
    unsigned int _posESC = -1; //转义字符标记,表示是否有转义符,-1表示前面没有转义字符，否则表示转义字符的位置
    unsigned int _posBuf = 0; // 当前处理字符串的位置
    unsigned int _posTbuf = 0; // 当前保存处理之后字符串的位置
    while (_posBuf < cnt)
    {
        if((int)_posESC == -1)
        {
            if(buf[_posBuf] == '\n')  
            {
                // 语法错误
                // to do
                return -1;
            }
            if(buf[_posBuf] == '\\') //发现转义字符
            {
                _posESC = _posBuf;
            }
            else
            {
                buf[_posTbuf++] = buf[_posBuf];
            }
        }
        else
        {
            int i = 0;
            for(; i!= sizeof(ESTR_CHs)/sizeof(ESTR_CHs[0]); i++) // 查找单字符转换的类型
            {
                if( ESTR_CHs[i][0] == buf[_posBuf] )
                {
                    _posESC = -1;
                    break;
                }
            }
            if (i < 12) // 直接将此转义字符转换为正确字符
            {
                buf[_posTbuf++] = ESTR_CHs[i][1]; //直接把字符转换为
            }
            else if(i == 12) // 遇到 'x'
            {
                assert(ESTR_CHs[i][0] == 'x');
                _posBuf++;
                unsigned int posBufTmp = _posBuf; //指示 'x' 字符下一个开始的地方 
                unsigned int valueTmp = 0; // hex值
                while (_posBuf < cnt && -1 != HexAddtoInt(buf[_posBuf],&valueTmp))
                {
                    _posBuf++;
                }
                buf[_posTbuf++] = (posBufTmp==_posBuf ? 'x' : (valueTmp & 0xFF)); //发现x后面的就不是正确的hex字符,把前面的 x当成 x处理
                continue; // 最后一个字符没有处理 ，需要跳过最后的 _posBuf++
            }
            else if(i == 13) // 处理 urf16EB字符，4个字符一组，小于4个有效字符报错，大于4个无视
            {
                assert(ESTR_CHs[i][0] == 'u');
                _posBuf++;
                unsigned int posBufTmp = _posBuf; //指示 'x' 字符下一个开始的地方 
                unsigned int valueTmp = 0; // hex值
                int i = 0;
                while (_posBuf < cnt && -1 != HexAddtoInt(buf[_posBuf],&valueTmp) && i < 4)
                {
                    _posBuf++;i++;
                }
                if( i == 0)
                {
                    buf[_posTbuf++] = 'u';
                }
                else if(i != 4) // 
                {
                    //语法错误
                    // to do
                    return -1;
                }
                else
                {
                    int r = Utf16BE2Utf8(valueTmp,&buf[_posTbuf]);
                    _posTbuf += r;
                }
                continue; // 最后一个字符没有处理 ，需要跳过最后的 _posBuf++
            }
            else if(i >= 14 && i <= 21)
            {
                assert(ESTR_CHs[i][0] >= '0' && ESTR_CHs[i][0] <= '7');
                unsigned int valueTmp = ESTR_CHs[i][1]; // hex值
                _posBuf++;
                while (_posBuf < cnt && -1 != OcxAddtoInt(buf[_posBuf], &valueTmp))
                {
                    _posBuf++;
                }
                buf[_posTbuf++] = (valueTmp & 0xFF);  
                continue; // 最后一个字符没有处理 ，需要跳过最后的 _posBuf++
            }
            else if(i == 22) // 转义字符后是\n 忽略
            {
                assert(ESTR_CHs[i][0] == '\n');
            }
            else if(i == 23) //转义字符后是\r 检查下一个字符是不是
            {
                assert(ESTR_CHs[i][0] == '\r');
                _posBuf++;
                if(_posBuf < cnt)
                {
                    if(buf[_posBuf] !='\n')
                    {
                        buf[_posTbuf++] = '\r';
                    }
                } 
            }
            else /*if(i >= sizeof(ESTR_CHs)/sizeof(ESTR_CHs[0])) */ //没有找到 不增加 _posBuf 再次处理这个字符
            {
                buf[_posTbuf++] = buf[_posBuf];  
            }
        }
        _posBuf++; //处理下一个字符
    }
    return _posTbuf;
}

/**
 * @brief 检查结束字符
 * 
 * @param pcfg 
 * @param pPosBuf 
 * @param markSeparator 
 * @return int
 */
int _CfgParse_GetEstr_Separator(cfg_t* pcfg,unsigned int*pPosBuf, int markSeparator)
{
    // 继续查找 分隔符, 可能是 '\'' 或 '"'或 '`', 要求分隔符前不能有转义字符
    if((*pPosBuf) == 0 && pcfg->parse.pbuf[(*pPosBuf)] == markSeparator) //防止第一个字符就是分隔符
    {
        (*pPosBuf)++;
        return 0;
    }
    while ((*pPosBuf) < pcfg->parse.szBuf &&(! (pcfg->parse.pbuf[(*pPosBuf)] == markSeparator && pcfg->parse.pbuf[(*pPosBuf)-1]!= '\\')) )
    {
        // if(pcfg->parse.pbuf[(*pPosBuf)] == '\n' && 
        //     (( (*pPosBuf)<1 || (pcfg->parse.pbuf[(*pPosBuf)-1] != '\r' && pcfg->parse.pbuf[(*pPosBuf)-1] != '\\')) || 
        //      ( (*pPosBuf)<2 ||(pcfg->parse.pbuf[(*pPosBuf)-1] == '\r' && pcfg->parse.pbuf[(*pPosBuf)-2] != '\\') ) ) )
        // {
        //     // 语法错误
        //     // to do
        //     return -1;
        // }
        (*pPosBuf)++;
    }
    if((*pPosBuf) >= pcfg->parse.szBuf )
    {
        if(pcfg->parse.pbuf[(*pPosBuf) -1] == '\\') // 如果缓存最后一个字符是 '\\' 退回一个字符，防止 缓存最一个字符是
        {
            (*pPosBuf)--;
        }
        return EOF_OF_BUF;
    }
    return 0;
}
/**
 * @brief  处理 带转义字符的 str
 * 
 * @param pcfg 
 * @param pcpd 
 * @return int 
 */
int _CfgParse_GetEstr(cfg_t* pcfg, cfgparsedata_t* pcpd)
{
    assert(pcpd != NULL && pcpd->type == CFG_TYPE_ESTR); // 对于 estr pcpd 必须有值 且类型为 CFG_TYPE_ESTR
    unsigned int _posBuf = pcfg->parse.posBuf;
    int _markSeparator = -1;// 分隔符，可能是 '\'' 或 '"'或 '`'
    // 以下是检查 pcpd 以处理字符串跨跃缓存的情况 （不在一个缓存中，被分成两部分读取）
    if(pcpd->stage == CFG_PARSE_STAGE_ESTR)
    {
        _markSeparator = (int)pcpd->value.llval;
        // 继续查找 分隔符, 可能是 '\'' 或 '"'或 '`', 要求分隔符前不能有转义字符
        int r = _CfgParse_GetEstr_Separator(pcfg, &_posBuf, _markSeparator);
        if(r == -1)
        {
            return -1;
        }
        else if(r == EOF_OF_BUF)
        {
            pcfg->parse.pos += _posBuf - pcfg->parse.posBuf;
            pcfg->parse.posBuf = _posBuf;
            return EOF_OF_BUF;
        }
        goto _CfgParse_GetEstr_AddtoTree;
    }
    if(_markSeparator == -1 && (!(pcfg->parse.pbuf[_posBuf] == '"' || pcfg->parse.pbuf[_posBuf] == '\'' || pcfg->parse.pbuf[_posBuf] == '`')))
    {
        return -2;
    }
    _markSeparator = pcfg->parse.pbuf[_posBuf++]; // 分隔符，可能是 '\'' 或 '"'或 '`'
    pcfg->parse.pos++;pcfg->parse.posBuf++;
    {
        int r = _CfgParse_GetEstr_Separator(pcfg, &_posBuf, _markSeparator);
        if(r == -1)
        {
            return -1;
        }
        else if(r == EOF_OF_BUF)
        {
            pcpd->value.llval = _markSeparator;
            pcpd->stage = CFG_PARSE_STAGE_ESTR;
            pcpd->sposVal = pcfg->parse.posBuf;
            pcfg->parse.pos += _posBuf - pcfg->parse.posBuf;
            pcfg->parse.posBuf = _posBuf;
            return EOF_OF_BUF;
        }
        pcpd->sposVal = pcfg->parse.pos;
        pcpd->lenVal = _posBuf - pcfg->parse.posBuf;
        pcfg->parse.pos += pcpd->lenVal + 1; // 加1 是跳过最后的 分隔符
        pcfg->parse.posBuf += pcpd->lenVal + 1; // 加1 是跳过最后的 分隔符
    }
    _CfgParse_GetEstr_AddtoTree:
    {
        cfgdata_t cd = {
            .type=CFG_TYPE_ESTR,
        };
        char * p[2] ={cd.key,cd.value.sval};
        if(-1 == fstrdup2(pcfg->parse.fp,pcpd->sposKey,pcpd->lenKey,pcpd->sposVal,pcpd->lenVal,p,_CfgParse_GetEstr_Parse,pcfg))
        {
            return -1;
        }
        if(NULL == TreeNodeAddChild2(pcfg->ptRoot, pcpd->parentNode,&cd))
        {
            if(cd.key) {free(cd.key);}else if(cd.value.sval){free(cd.value.sval);}
            return -1;
        }
        ((cfgdata_t*) (pcpd->parentNode->data))->value.llval ++; // 容器子元素数量加1
        Stack2Pop(&pcfg->parse.stackParseData);
    }
    return 0;
}


/**
 * @brief 检查结束字符
 * 
 * @param pcfg 
 * @param pPosBuf 
 * @param markSeparator 
 * @return int
 */
int _CfgParse_GetBase64_Separator(cfg_t* pcfg,unsigned int*pPosBuf, int markSeparator)
{
    // 继续查找 分隔符, 可能是 '\'' 或 '"'或 '`', 要求分隔符前不能有转义字符
    if((*pPosBuf) == 0 && pcfg->parse.pbuf[(*pPosBuf)] == markSeparator) //防止第一个字符就是分隔符
    {
        (*pPosBuf)++;
        return 0;
    }
    while ((*pPosBuf) < pcfg->parse.szBuf &&(! (pcfg->parse.pbuf[(*pPosBuf)] == markSeparator && pcfg->parse.pbuf[(*pPosBuf)-1]!= '\\')) )
    {
        if(pcfg->parse.pbuf[(*pPosBuf)] == '\n' && 
            (( (*pPosBuf)<1 || (pcfg->parse.pbuf[(*pPosBuf)-1] != '\r' && pcfg->parse.pbuf[(*pPosBuf)-1] != '\\')) || 
             ( (*pPosBuf)<2 ||(pcfg->parse.pbuf[(*pPosBuf)-1] == '\r' && pcfg->parse.pbuf[(*pPosBuf)-2] != '\\') ) ) )
        {
            // 语法错误
            // to do
            return -1;
        }
        (*pPosBuf)++;
    }
    if((*pPosBuf) >= pcfg->parse.szBuf )
    {
        if(pcfg->parse.pbuf[(*pPosBuf) -1] == '\\') // 如果缓存最后一个字符是 '\\' 退回一个字符，防止 缓存最一个字符是
        {
            (*pPosBuf)--;
        }
        return EOF_OF_BUF;
    }
    return 0;
}

/**
 * @brief 根据 buf 来处理base64字符，并放在 buf 之中，返回处理之后字符数量
 * 
 * @param pcfg 
 * @param buf 
 * @param cnt 传入的 buf 大小
 * @return int 返回处理之扣的字符数量 单位：字节
 */
int _CfgParse_GetBase64_Parse(cfg_t* pcfg, char* buf,unsigned int cnt)
{
    //通过查表法转义 base64: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
    char BASE64[]={ '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',62,'\xff','\xff','\xff',63,// !"#$%&'()*+,-./
                    52,53,54,55,56,57,58,59,60,61,'\xff','\xff','\xff','\xff','\xff','\xff',//0123456789:;<=>?
                    '\xff',0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,//@ABCDEFGHIJKLMNO
                    15,16,17,18,19,20,21,22,23,24,25,'\xff','\xff','\xff','\xff','\xff',//PQRSTUVWXYZ[\]^_
                    '\xff',26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,//`abcdefghijklmno
                    41,42,43,44,45,46,47,48,49,50,51,'\xff','\xff','\xff','\xff','\xff',//pqrstuvwxyz{|}~
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff', };
    unsigned int _posBuf = 0; // 当前处理字符串的位置
    unsigned int _posTbuf = 0; // 当前保存处理之后字符串的位置
    unsigned int _value = 0;
    unsigned int _stage = 18;
    while (_posBuf < cnt)
    {
        if(buf[_posBuf] == '\\' )
        {
            _posBuf++;
            if(!(_posBuf < cnt && (buf[_posBuf] == '\n' || (buf[_posBuf] == '\r' && (_posBuf++,_posBuf < cnt) && buf[_posBuf] == '\n'))))
            {
                // 转义符在此只能用于换行，其它情况均为错误 
                return -1;
            }
            _posBuf++;
            continue;
        }
        else if ((unsigned char)BASE64[buf[_posBuf]] !=  0xff)
        {
            _value = BASE64[buf[_posBuf]] << _stage;
            _stage -= 6;
        }
        if(_stage == 0)
        {
            buf[_posTbuf++] = (_value & 0x0F00)>>16;
            buf[_posTbuf++] = (_value & 0x00F0)>>8;
            buf[_posTbuf++] = (_value & 0x000F)>>0;
            _stage = 18;
            _value =0;
        }
        _posBuf++;
    }
    while (_stage > 0)
    {
         buf[_posTbuf++] = '=';
         _stage -= 6;
    }
    return _posTbuf;
}

/**
 * @brief 处理 base64格式的 str
 * 
 * @param pcfg 
 * @param pcpd 
 * @return int 
 */
int _CfgParse_GetBase64(cfg_t* pcfg, cfgparsedata_t* pcpd)
{
    assert(pcpd != NULL && pcpd->type == CFG_TYPE_BASE64); // 对于 base64 pcpd 必须有值 且类型为 CFG_TYPE_BASE64
    unsigned int _posBuf = pcfg->parse.posBuf;
    int _markSeparator = -1;// 分隔符，可能是 '\'' 或 '"'或 '`'
    // 以下是检查 pcpd 以处理字符串跨跃缓存的情况 （不在一个缓存中，被分成两部分读取）
    if(pcpd->stage == CFG_TYPE_BASE64)
    {
        _markSeparator = (int)pcpd->value.llval;
        // 继续查找 分隔符, 可能是 '\'' 或 '"'或 '`', 要求分隔符前不能有转义字符
        int r = _CfgParse_GetBase64_Separator(pcfg, &_posBuf, _markSeparator);
        if(r == -1)
        {
            return -1;
        }
        else if(r == EOF_OF_BUF)
        {
            pcfg->parse.pos += _posBuf - pcfg->parse.posBuf;
            pcfg->parse.posBuf = _posBuf;
            return EOF_OF_BUF;
        }
        goto _CfgParse_GetBase64_AddtoTree;
    }
    if(_markSeparator == -1 && (!(pcfg->parse.pbuf[_posBuf] == '"' || pcfg->parse.pbuf[_posBuf] == '\'' || pcfg->parse.pbuf[_posBuf] == '`')))
    {
        return -2;
    }
    _markSeparator = pcfg->parse.pbuf[_posBuf++]; // 分隔符，可能是 '\'' 或 '"'或 '`'
    pcfg->parse.pos++;pcfg->parse.posBuf++;
    {
        int r = _CfgParse_GetBase64_Separator(pcfg, &_posBuf, _markSeparator);
        if(r == -1)
        {
            return -1;
        }
        else if(r == EOF_OF_BUF)
        {
            pcpd->value.llval = _markSeparator;
            pcpd->stage = CFG_PARSE_STAGE_ESTR;
            pcpd->sposVal = pcfg->parse.posBuf;
            pcfg->parse.pos += _posBuf - pcfg->parse.posBuf;
            pcfg->parse.posBuf = _posBuf;
            return EOF_OF_BUF;
        }
        pcpd->sposVal = pcfg->parse.pos;
        pcpd->lenVal = _posBuf - pcfg->parse.posBuf;
        pcfg->parse.pos += pcpd->lenVal + 1; // 加1 是跳过最后的 分隔符
        pcfg->parse.posBuf += pcpd->lenVal + 1; // 加1 是跳过最后的 分隔符
    }
    _CfgParse_GetBase64_AddtoTree:
    {
        cfgdata_t cd = {
            .type=CFG_TYPE_BASE64,
        };
        char * p[2] ={cd.key,cd.value.sval};
        if(-1 == fstrdup2(pcfg->parse.fp,pcpd->sposKey,pcpd->lenKey,pcpd->sposVal,pcpd->lenVal,p,_CfgParse_GetBase64_Parse,pcfg))
        {
            return -1;
        }
        if(NULL == TreeNodeAddChild2(pcfg->ptRoot, pcpd->parentNode,&cd))
        {
            if(cd.key) {free(cd.key);}else if(cd.value.sval){free(cd.value.sval);}
            return -1;
        }
        ((cfgdata_t*) (pcpd->parentNode->data))->value.llval ++; // 容器子元素数量加1
        Stack2Pop(&pcfg->parse.stackParseData);
    }
    return 0;
}

/**
 * @brief 检查结束字符
 * 
 * @param pcfg 
 * @param pPosBuf 
 * @param markSeparator 
 * @return int
 */
int _CfgParse_GetHex_Separator(cfg_t* pcfg,unsigned int*pPosBuf, int markSeparator)
{
    // 继续查找 分隔符, 可能是 '\'' 或 '"'或 '`', 要求分隔符前不能有转义字符
    if((*pPosBuf) == 0 && pcfg->parse.pbuf[(*pPosBuf)] == markSeparator) //防止第一个字符就是分隔符
    {
        (*pPosBuf)++;
        return 0;
    }
    while ((*pPosBuf) < pcfg->parse.szBuf &&(! (pcfg->parse.pbuf[(*pPosBuf)] == markSeparator && pcfg->parse.pbuf[(*pPosBuf)-1]!= '\\')) )
    {
        if(pcfg->parse.pbuf[(*pPosBuf)] == '\n' && 
            (( (*pPosBuf)<1 || (pcfg->parse.pbuf[(*pPosBuf)-1] != '\r' && pcfg->parse.pbuf[(*pPosBuf)-1] != '\\')) || 
             ( (*pPosBuf)<2 ||(pcfg->parse.pbuf[(*pPosBuf)-1] == '\r' && pcfg->parse.pbuf[(*pPosBuf)-2] != '\\') ) ) )
        {
            // 语法错误
            // to do
            return -1;
        }
        (*pPosBuf)++;
    }
    if((*pPosBuf) >= pcfg->parse.szBuf )
    {
        if(pcfg->parse.pbuf[(*pPosBuf) -1] == '\\') // 如果缓存最后一个字符是 '\\' 退回一个字符，防止 缓存最一个字符是
        {
            (*pPosBuf)--;
        }
        return EOF_OF_BUF;
    }
    return 0;
}

/**
 * @brief 根据 buf 来处理 Hex 字符，并放在 buf 之中，返回处理之后字符数量
 * 
 * @param pcfg 
 * @param buf 
 * @param cnt 传入的 buf 大小
 * @return int 返回处理之扣的字符数量 单位：字节
 */
int _CfgParse_GetHex_Parse(cfg_t* pcfg, char* buf,unsigned int cnt)
{
    //通过查表法转义 base64: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
    char HEX[]={ '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',// !"#$%&'()*+,-./
                    0,1,2,3,4,5,6,7,8,9,'\xff','\xff','\xff','\xff','\xff','\xff',//0123456789:;<=>?
                    '\xff',10,11,12,13,14,15,'\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',//@ABCDEFGHIJKLMNO
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',//PQRSTUVWXYZ[\]^_
                    '\xff',10,11,12,13,14,15,'\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',//`abcdefghijklmno
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',//pqrstuvwxyz{|}~
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',
                    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff', };
    unsigned int _posBuf = 0; // 当前处理字符串的位置
    unsigned int _posTbuf = 0; // 当前保存处理之后字符串的位置
    unsigned int _value = 0;
    unsigned int _stage = 8;
    while (_posBuf< cnt)
    {
        if(buf[_posBuf] == '\\' )
        {
            _posBuf++;
            if(!(_posBuf < cnt && (buf[_posBuf] == '\n' || (buf[_posBuf] == '\r' && (_posBuf++,_posBuf < cnt) && buf[_posBuf] == '\n'))))
            {
                // 转义符在此只能用于换行，其它情况均为错误 
                return -1;
            }
            _posBuf++;
            continue;
        }
        else if ((unsigned char)HEX[buf[_posBuf]] != 0xff )
        {
            _value = HEX[buf[_posBuf]] << _stage;
            _stage -= 4;
        }
        if(_stage == 0)
        {
            buf[_posTbuf++] = _value;
            _stage = 8;
            _value =0;
        }
        _posBuf++;
    }
    return _posTbuf;

}

/**
 * @brief 处理 hex 格式的 str , 一个字符转换为两个字节的 hex，字符串最少两个字节一组
 * 
 * @param pcfg 
 * @param pcpd 
 * @return int 
 */
int _CfgParse_GetHex(cfg_t* pcfg, cfgparsedata_t* pcpd)
{
    assert(pcpd != NULL && pcpd->type == CFG_TYPE_HEX); // 对于 base64 pcpd 必须有值 且类型为 CFG_TYPE_HEX
    unsigned int _posBuf = pcfg->parse.posBuf;
    int _markSeparator = -1;// 分隔符，可能是 '\'' 或 '"'或 '`'
    // 以下是检查 pcpd 以处理字符串跨跃缓存的情况 （不在一个缓存中，被分成两部分读取）
    if(pcpd->stage == CFG_TYPE_HEX)
    {
        _markSeparator = (int)pcpd->value.llval;
        // 继续查找 分隔符, 可能是 '\'' 或 '"'或 '`', 要求分隔符前不能有转义字符
        int r = _CfgParse_GetHex_Separator(pcfg, &_posBuf, _markSeparator);
        if(r == -1)
        {
            return -1;
        }
        else if(r == EOF_OF_BUF)
        {
            pcfg->parse.pos += _posBuf - pcfg->parse.posBuf;
            pcfg->parse.posBuf = _posBuf;
            return EOF_OF_BUF;
        }
        goto _CfgParse_GetHex_AddtoTree;
    }
    if(_markSeparator == -1 && (!(pcfg->parse.pbuf[_posBuf] == '"' || pcfg->parse.pbuf[_posBuf] == '\'' || pcfg->parse.pbuf[_posBuf] == '`')))
    {
        return -2;
    }
    _markSeparator = pcfg->parse.pbuf[_posBuf++]; // 分隔符，可能是 '\'' 或 '"'或 '`'
    pcfg->parse.pos++;pcfg->parse.posBuf++;
    {
        int r = _CfgParse_GetBase64_Separator(pcfg, &_posBuf, _markSeparator);
        if(r == -1)
        {
            return -1;
        }
        else if(r == EOF_OF_BUF)
        {
            pcpd->value.llval = _markSeparator;
            pcpd->stage = CFG_PARSE_STAGE_ESTR;
            pcpd->sposVal = pcfg->parse.posBuf;
            pcfg->parse.pos += _posBuf - pcfg->parse.posBuf;
            pcfg->parse.posBuf = _posBuf;
            return EOF_OF_BUF;
        }
        pcpd->sposVal = pcfg->parse.pos;
        pcpd->lenVal = _posBuf - pcfg->parse.posBuf;
        pcfg->parse.pos += pcpd->lenVal + 1; // 加1 是跳过最后的 分隔符
        pcfg->parse.posBuf += pcpd->lenVal + 1; // 加1 是跳过最后的 分隔符
    }
    _CfgParse_GetHex_AddtoTree:
    {
        cfgdata_t cd = {
            .type=CFG_TYPE_ESTR,
        };
        char * p[2] ={cd.key,cd.value.sval};
        if(-1 == fstrdup2(pcfg->parse.fp,pcpd->sposKey,pcpd->lenKey,pcpd->sposVal,pcpd->lenVal,p,_CfgParse_GetHex_Parse,pcfg))
        {
            return -1;
        }
        if(NULL == TreeNodeAddChild2(pcfg->ptRoot, pcpd->parentNode,&cd))
        {
            if(cd.key) {free(cd.key);}else if(cd.value.sval){free(cd.value.sval);}
            return -1;
        }
        ((cfgdata_t*) (pcpd->parentNode->data))->value.llval ++; // 容器子元素数量加1
        Stack2Pop(&pcfg->parse.stackParseData);
    }
    return 0;
}

/**
 * @brief 分析comment时查找 \n
 * 
 * @param pcfg 
 * @param pPosBuf 
 * @return int 
 */
int _CfgParse_GetComment_lf(cfg_t* pcfg, unsigned int* pPosBuf)
{
    while((*pPosBuf) < pcfg->parse.szBuf)
    {
        if( pcfg->parse.pbuf[(*pPosBuf)]  == '\n' )
        {
            (*pPosBuf)++; // 跳过 \n
            if((*pPosBuf) > 1 && pcfg->parse.pbuf[(*pPosBuf) - 1 ]  == '\\' )
            {
                continue;
            }
            pcfg->parse.line++;
            return 0;
        }
        (*pPosBuf)++;
    }
    if(pcfg->parse.pbuf[(*pPosBuf) - 1 ]  == '\\')
    {
        (*pPosBuf)--;
    }
    return EOF_OF_BUF;
}
/**
 * @brief 分析 comment时查找 * /
 * 
 * @param pcfg 
 * @param pPosBuf 
 * @return int 
 */
int _CfgParse_GetComment_rcomment(cfg_t* pcfg, unsigned int* pPosBuf)
{
    while((*pPosBuf) < pcfg->parse.szBuf)
    {
        if(pcfg->parse.pbuf[(*pPosBuf)]  == '\n') { pcfg->parse.line ++; }
        if( pcfg->parse.pbuf[(*pPosBuf)]  == '*' )
        {
            (*pPosBuf)++;
            if( (*pPosBuf) >= pcfg->parse.szBuf )
            {
                (*pPosBuf)--;
                return EOF_OF_BUF;
            }
            if( pcfg->parse.pbuf[(*pPosBuf) ]  == '/' )
            {
                (*pPosBuf)++; // 跳过最后的 '/'
                return 0;
            }
        }
        (*pPosBuf)++;
    }
    return EOF_OF_BUF;
}
/**
 * @brief 处理注释
 * 
 * @param pcfg 
 * @param pcpd 
 * @return int 
 */
int _CfgParse_GetComment(cfg_t* pcfg, cfgparsedata_t* pcpd)
{
    enum cfgtype_e _type = -1;
    enum cfgparsestage_e _stage = -1;
    unsigned int _posBuf = pcfg->parse.posBuf;
    if(pcpd)
    {
        if(pcpd->type == CFG_TYPE_COMMENT && pcpd->stage == CFG_PARSE_STAGE_CONTENT)
        {
            goto _CfgParse_GetComment_11; // 跳转去执行查找 字符 \n
        }
        else if(pcpd->type == CFG_TYPE_COMMENT_MULTILINE && pcpd->stage == CFG_PARSE_STAGE_CONTENT_MULTILINE)
        {
            goto _CfgParse_GetComment_22; // 跳转去执行查找 * 和 /
        }
    }
    if( _posBuf + 1 < pcfg->parse.szBuf)
    {
        if( '/' == pcfg->parse.pbuf[_posBuf] && '/' == pcfg->parse.pbuf[_posBuf + 1]) // 单行注释，直到行尾
        {
            pcfg->parse.pos+=2;pcfg->parse.posBuf+=2; //pcfg->parse.line++;
            _posBuf+=2; 
            
            _stage = CFG_PARSE_STAGE_CONTENT;
            _CfgParse_GetComment_11:
            _type = CFG_TYPE_COMMENT;
            if(_CfgParse_GetComment_lf(pcfg, &_posBuf) == EOF_OF_BUF)
            {
                goto _CfgParse_GetComment_EOF_OF_BUF;
            }
        }
        else if( '/' == pcfg->parse.pbuf[_posBuf] && '*' == pcfg->parse.pbuf[_posBuf + 1]) // 多行注释，直到 * /
        {
            pcfg->parse.pos+=2;pcfg->parse.posBuf+=2;
            _posBuf+=2;
            _stage = CFG_PARSE_STAGE_CONTENT_MULTILINE;
            _CfgParse_GetComment_22:
            _type = CFG_TYPE_COMMENT_MULTILINE; 
            if(_CfgParse_GetComment_rcomment(pcfg, &_posBuf) == EOF_OF_BUF)
            {
                goto _CfgParse_GetComment_EOF_OF_BUF;
            }
        }
        else 
        {
            return -2;
        }
    }
    else if(_posBuf < pcfg->parse.szBuf) // 防止在buf最后一个字符又不是 注释符
    {
        return -2;
    }
    if(pcfg->signSaveComment) // 同样保存注释
    { 
        char* pstr = NULL;
        unsigned int pos = -1;
        unsigned int len= 0;
        if(pcpd && CfgTypeIsComment (pcpd->type) )
        {
            pos = pcpd->sposVal; len = pcfg->parse.pos - pos + (_posBuf - pcfg->parse.szBuf);
        }
        else 
        {
            pos =pcfg->parse.pos; len = _posBuf - pcfg->parse.posBuf;
        }
        if(-1 == fstrdup(pcfg->parse.fp, &pos, &len, &pstr,1))
        {
            return -1;
        }
        cfgdata_t cd = {
            .type = _type, .key = 0, .klen = -1, .value.sval = pstr , .vlen = len,
        };
        treenode_t *parentNode = _GetParentNodebypcpd(pcfg,pcpd);
        if(NULL == TreeNodeAddChild2(pcfg->ptRoot,parentNode,&cd))
        {
            if(cd.key){free(cd.key);}
            return -1;
        }
    }
    DebugPrintf("Find:Comment:pos:%u,len:%u\n",pcfg->parse.posBuf, _posBuf - pcfg->parse.posBuf);
    pcfg->parse.pos+=(_posBuf - pcfg->parse.posBuf);pcfg->parse.posBuf= _posBuf;
    if(_CfgParse_SkipSpace(pcfg) == EOF_OF_BUF) //防止注释后面有空格
    {
        return EOF_OF_BUF;
    }
    return 0;
    _CfgParse_GetComment_EOF_OF_BUF:
    if(_stage != -1)
    {
        cfgparsedata_t cpd = {
            .type= _type, .stage = _stage,
            .sposKey = -1,.lenKey= 0, .sposVal = pcfg->parse.pos,.lenVal = 0,
            .parentNode = pcpd?pcpd->parentNode:TreeRoot(pcfg->ptRoot),
        };
        if(Stack2Push(&pcfg->parse.stackParseData, &cpd) == NULL)
        {
            pcfg->diagnosis.err = CFG_ERR_ADD_STACK;
            pcfg->diagnosis.line = pcfg->parse.line;
            pcfg->diagnosis.pos = pcfg->parse.pos + (_posBuf - pcfg->parse.posBuf);
            return -1;
        }        
    }
    pcfg->parse.pos+=(_posBuf - pcfg->parse.posBuf);pcfg->parse.posBuf = _posBuf;
    return EOF_OF_BUF;
}

/**
 * @brief  从当前缓存位置获取关键字，压入 cfg_t::parse::stackParseData，需要先调用 _CfgParse_SkipSpace 确保前面无空白字符，并且确保没有到达缓存结束位置
 * 
 * @param pcfg 
 * @return int 
 */
int _CfgParse_GetKeywrods( cfg_t* pcfg, cfgparsedata_t* pcpd)
{
    unsigned int _posBuf = pcfg->parse.posBuf;
    if(isalpha(pcfg->parse.pbuf[pcfg->parse.posBuf]) || pcfg->parse.pbuf[pcfg->parse.posBuf] == '_') // 检查是否是变量名或关键字
    {
        // 1. 检查直到非(字母/数字/_)
        while (_posBuf <  pcfg->parse.szBuf && (isalnum(pcfg->parse.pbuf[_posBuf]) || pcfg->parse.pbuf[_posBuf] == '_'))
        {
            _posBuf++;
        }
        if(_posBuf ==  pcfg->parse.szBuf)
        {
            return EOF_OF_BUF;
        }
        #ifndef NDEBUG
            char fmt[32];
            sprintf(fmt, "Keyword:%%.%ds,Pos:%%u\n",_posBuf-pcfg->parse.posBuf);
            DebugPrintf(fmt,&pcfg->parse.pbuf[pcfg->parse.posBuf], pcfg->parse.posBuf);        
        #endif

        //查看是否是关键字
        struct _KEYWORDS { const char* name; unsigned len;enum cfgtype_e type; } KEYWORDS[]=
        {
            {"null",4,CFG_TYPE_NULL}, {"true",4,CFG_TYPE_BOOL}, {"false",5,CFG_TYPE_BOOL},
            {"group",5,CFG_TYPE_GROUP}, {"array",5,CFG_TYPE_ARRAY}, {"int",3,CFG_TYPE_INT},
            {"int8",4,CFG_TYPE_INT8}, {"int16",5,CFG_TYPE_INT16}, {"int32",5,CFG_TYPE_INT32},
            {"int64",5,CFG_TYPE_INT64}, {"uint",4,CFG_TYPE_UINT}, {"uint8",5,CFG_TYPE_UINT8},
            {"uint16",6,CFG_TYPE_UINT16}, {"uint32",6,CFG_TYPE_UINT32}, {"uint64",6,CFG_TYPE_UINT64},
            {"bool",4,CFG_TYPE_BOOL}, {"float",5,CFG_TYPE_FLOAT}, {"complex",7,CFG_TYPE_COMPLEX},
            {"str",3,CFG_TYPE_STR}, {"estr",4,CFG_TYPE_ESTR}, {"base64",6,CFG_TYPE_BASE64},
            {"hex",3,CFG_TYPE_HEX},
        };
        unsigned int len = _posBuf - pcfg->parse.posBuf;
        unsigned int signKeyword = -1;
        for(int i = 0; i != sizeof(KEYWORDS)/sizeof(KEYWORDS[0]); i++) // 检查关键字，如果检查到就返回0
        {
            if(len == KEYWORDS[i].len && 0 == memcmp(&pcfg->parse.pbuf[pcfg->parse.posBuf], KEYWORDS[i].name, len))
            {
                signKeyword = i;
                break;
            }
        }
        if( signKeyword >= 3 && signKeyword < sizeof(KEYWORDS)/sizeof(KEYWORDS[0]) ) // 检查到类型关键字 例如 group: 或 estr:
        {
            int markAddtoStack = 1; //是否向栈添加一个 cfgparsedata_t
            if( pcpd )
            {
                if(pcpd->type == CFG_TYPE_NULL) //前面循环已在栈中，类型为 CFG_TYPE_NULL，说明有键名，是键值对
                {
                    pcpd->type = KEYWORDS[signKeyword].type;
                    pcpd->stage = CFG_PARSE_STAGE_KEYVALUE_TYPE;
                    markAddtoStack = 0;
                }
                else // 无键名， pcpd 是值容器, 如果不是 值容器，说明是向键值对容器添加值，错误
                {
                    if(! CfgTypeIsVContainer(pcpd->type))
                    {
                        pcfg->diagnosis.err = CFG_ERR_V_ADDTO_NONCONTAINER;
                        pcfg->diagnosis.line = pcfg->parse.line;
                        pcfg->diagnosis.pos = pcfg->parse.pos;
                    }
                }
            }
            if(markAddtoStack)
            {
                cfgparsedata_t cpd = { // 准备插入栈的有名类型，再次循环要看到 :
                    .type = KEYWORDS[signKeyword].type, .stage = CFG_PARSE_STAGE_TYPE,
                    .sposKey = -1, .lenKey = 0, .sposVal = -1, .lenVal = 0,
                    .parentNode = _GetParentNodebypcpd(pcfg, pcpd),
                };
                if(NULL == (cfgparsedata_t*) Stack2Push(&pcfg->parse.stackParseData, &cpd))
                {
                    //系统错误
                    pcfg->diagnosis.err = CFG_ERR_ADD_STACK;
                    pcfg->diagnosis.line = pcfg->parse.line;
                    pcfg->diagnosis.pos = pcfg->parse.pos;
                    return -1;
                }
            }
            goto _CfgParse_GetKeywrods_Success;
        }
        else if(signKeyword < 3) // 是 null/true/false值
        {
            cfgdata_t cd = {
                .type = KEYWORDS[signKeyword].type,
                .value.llval = signKeyword == 1? 1:0, 
            };
            treenode_t* parentNode = _GetParentNodebypcpd(pcfg, pcpd);
            if(NULL == TreeNodeAddChild2(pcfg->ptRoot, _GetParentNodebypcpd(pcfg, pcpd), &cd))
            {
                //系统错误
                pcfg->diagnosis.err = CFG_ERR_ADD_TREE_LEAF;
                pcfg->diagnosis.line = pcfg->parse.line;
                pcfg->diagnosis.pos = pcfg->parse.pos;
                return -1;
            }
            ((cfgdata_t*) (parentNode->data))->value.llval ++; // 容器子元素数量加1
            if(pcpd&& pcpd->type == CFG_TYPE_NULL || pcpd&& pcpd->type == CFG_TYPE_BOOL)
            {
                Stack2Pop(&pcfg->parse.stackParseData);
            }
            goto _CfgParse_GetKeywrods_Success;
        }
        // 没有在上面返回，说明是检测到一个变量名, 必须是一个键值对，下面检查语法合法性
        if(!(pcpd == NULL || ( CfgTypeIsKVContainer(pcpd->type) && (pcpd->stage & 0xFFF0) == CFG_PARSE_STAGE_GROUP ) ) ) // 非（上级是 root或上级是 group /map）
        {
            // 变量名上级不是 合法，即不应跟有变量名，语法错误
            pcfg->diagnosis.err = CFG_ERR_KV_ADDTO_NONCONTAINER;
            pcfg->diagnosis.line = pcfg->parse.line;
            pcfg->diagnosis.pos = pcfg->parse.pos;
            return -1;
        }
        cfgparsedata_t cpd = { //准备插入栈的变量名
            .type = CFG_TYPE_NULL,
            .stage = CFG_PARSE_STAGE_KEYVALUE_KEY,
            .sposKey = pcfg->parse.pos, .lenKey = _posBuf - pcfg->parse.posBuf, .sposVal = -1, .lenVal = -1,
            .parentNode = _GetParentNodebypcpd(pcfg, pcpd),
        };
        if(NULL == (pcpd = (cfgparsedata_t*) Stack2Push(&pcfg->parse.stackParseData, &cpd)))
        {
            // 压栈错误 系统错误
            pcfg->diagnosis.err = CFG_ERR_KV_ADDTO_NONCONTAINER;
            pcfg->diagnosis.line = pcfg->parse.line;
            pcfg->diagnosis.pos = pcfg->parse.pos;
            return -1;
        }
        goto _CfgParse_GetKeywrods_Success;
    }
    //检查 group
    int r = _CfgParse_GetGroup(pcfg, pcpd);
    if(r != -2)
    {
        return r;
    }
    //检查 array
    r = _CfgParse_GetArray(pcfg,pcpd);
    if(r != -2)
    {
        return r;
    }
    r = _CfgParse_GetNumber(pcfg, pcpd);
    if(r != -2) 
    {
        return r;
    }
    r = _CfgParse_GetStr(pcfg,pcpd);
    if(r != -2) 
    {
        return r;
    }
    r = _CfgParse_GetComment(pcfg, pcpd);
    if(r != -2) 
    {
        return r;
    }
    if( (pcfg->parse.pbuf[pcfg->parse.posBuf] == ',' || pcfg->parse.pbuf[pcfg->parse.posBuf] == ';')  &&
        (pcpd == NULL || (CfgTypeIsContainer( pcpd->type))) )
    {
        pcfg->parse.pos ++; pcfg->parse.posBuf ++; // 更新 pcfg->parse.posBuf,跳过 , 或 ; 
        return 0;
    }
    //检测错误字符，语法错语
    pcfg->diagnosis.err = CFG_ERR_CHAR;
    pcfg->diagnosis.line = pcfg->parse.line;
    pcfg->diagnosis.pos = pcfg->parse.pos;
    return -1;
    _CfgParse_GetKeywrods_Success: //成功返回
    pcfg->parse.pos += (_posBuf - pcfg->parse.posBuf);
    pcfg->parse.posBuf = _posBuf; // 更新 pcfg->parse.posBuf
    return 0;
}

/**
 * @brief 设置再次从文本中读取的标志
 * 
 * @param pcfg 
 */
void _CfgParse_SetRereadSign(cfg_t* pcfg)
{
    if(pcfg->parse.posBuf + 1 < pcfg->parse.szBuf)
    {
        size_t left = pcfg->parse.szBuf - pcfg->parse.posBuf;
        memcpy(pcfg->parse.pbuf, pcfg->parse.pbuf+pcfg->parse.posBuf, left);
        pcfg->parse.szBuf = (unsigned int)left;
    }
    pcfg->parse.signReloadRead = 1;
}

int CfgParse( cfg_t* pcfg )
{
    // //开启循环，读取 文本，用于分析
    size_t _szReaded;
    while ((_szReaded = fread(pcfg->parse.pbuf + pcfg->parse.szBuf, 
            1, 
            pcfg->parse.szPbuf - pcfg->parse.szBuf, 
            pcfg->parse.fp))) //读取最多MAX_PARSE_BUF byte的缓存
    {
        DebugPrintf("CfgParse:fread %llu\n",_szReaded);
        pcfg->parse.szBuf += (unsigned int)_szReaded;
        pcfg->parse.signReloadRead = 0; 
        // 开始做分析
        while( 0 == pcfg->parse.signReloadRead )
        {
            if(_CfgParse_SkipSpace(pcfg) == EOF_OF_BUF)
            {
                return EOF_OF_BUF;
            }
            cfgparsedata_t* pcpd = Stack2At(&pcfg->parse.stackParseData, -1); // 获取 栈的最上面的数据
            if(pcpd == NULL)  //栈是空的，说有没有在分析过程中，从头分析
            {
                switch (_CfgParse_GetKeywrods(pcfg, NULL))
                {
                case -1: // 错误
                    return -1;
                    break;
                case EOF_OF_BUF: 
                    _CfgParse_SetRereadSign(pcfg);
                    continue;
                case 0:
                    break;
                }
            }
            else
            {
                if(-1 == _CfgParse_GetComment(pcfg, pcpd))
                {
                    return -1;
                }
                switch (pcpd->stage)
                {
                case CFG_PARSE_STAGE_KEYVALUE_KEY: //查找  = 
                    if((pcfg->parse.pbuf[pcfg->parse.posBuf] == ',' || pcfg->parse.pbuf[pcfg->parse.posBuf] == ';') ) 
                    {
                        DebugPrintf("Next:root value ,pos:%u\n",pcfg->parse.posBuf);
                        if(!(pcpd->type == CFG_TYPE_STR && pcpd->sposKey != -1))
                        {
                            // 语法错误，在需要 = 处出来其它字符
                            pcfg->diagnosis.err = CFG_ERR_KV_NOT_EQUEL;
                            pcfg->diagnosis.line = pcfg->parse.line;
                            pcfg->diagnosis.pos = pcfg->parse.pos ;
                            return -1;
                        }
                        // 转换为 str
                        cfgdata_t cd = { .type = CFG_TYPE_STR, };
                        fstrdup(pcfg->parse.fp, &pcpd->sposKey, &pcpd->lenKey, &cd.value.sval, 1);
                        DebugPrintf("Tran:string:%s \n",cd.value.sval);
                        if(NULL == TreeNodeAddChild2(pcfg->ptRoot, pcpd->parentNode, &cd))
                        {
                            if(cd.value.sval){free(cd.value.sval);}
                            return -1;
                        }
                        ((cfgdata_t*) (pcpd->parentNode->data))->value.llval ++; // 容器子元素数量加1
                        Stack2Pop(&pcfg->parse.stackParseData); // 弹出栈最上面一个
                    }
                    else
                    {
                        if(pcfg->parse.pbuf[pcfg->parse.posBuf] != '=') // 不是 = 语法错误
                        {
                            // 语法错误 不是 =
                            pcfg->diagnosis.err = CFG_ERR_KV_NOT_EQUEL;
                            pcfg->diagnosis.line = pcfg->parse.line;
                            pcfg->diagnosis.pos = pcfg->parse.pos ;
                            return -1;
                        }
                        if(pcpd->type == CFG_TYPE_STR) 
                        {
                            pcpd->type = CFG_TYPE_NULL; 
                        }
                    }
                    DebugPrintf("Sign: =%c\n",' ');
                    pcfg->parse.pos++;pcfg->parse.posBuf++;
                    pcpd->stage = CFG_PARSE_STAGE_KEYVALUE_EQL;
                    break;
                case CFG_PARSE_STAGE_KEYVALUE_EQL: // 读到 =  ，查找 值
                    assert(pcpd != NULL);
                    switch (_CfgParse_GetKeywrods(pcfg, pcpd))
                    {
                    case -1: // 错误
                        return -1;
                        break;
                    case EOF_OF_BUF: 
                        _CfgParse_SetRereadSign(pcfg);
                        continue;
                    case 0:
                        break;
                    }
                    break;
                case CFG_PARSE_STAGE_KEYVALUE_TYPE:// 读到类型 查找 :
                    if(pcfg->parse.pbuf[pcfg->parse.posBuf] != ':') // 不是 : 语法错误
                    {
                        // 语法错误 要求是 ： 但是不是 :
                        // to do
                        return -1;
                    }
                    DebugPrintf("Sign: :%c\n",' ');
                    pcfg->parse.pos++;pcfg->parse.posBuf++;
                    pcpd->stage = CFG_PARSE_STAGE_KEYVALUE_COLON;
                    break;
                case CFG_PARSE_STAGE_KEYVALUE_COLON:
                { //使用查表法 
                    struct _TMP_STRUCT { enum cfgtype_e type; int (*fun)(cfg_t *, cfgparsedata_t *); } TMP_STRUCT[] = {
                        {CFG_TYPE_ESTR, _CfgParse_GetEstr},
                        {CFG_TYPE_ARRAY, _CfgParse_GetArray},{CFG_TYPE_GROUP, _CfgParse_GetGroup},
                        {CFG_TYPE_INT, _CfgParse_GetNumber},{CFG_TYPE_INT8, _CfgParse_GetNumber},{CFG_TYPE_INT16, _CfgParse_GetNumber},
                        {CFG_TYPE_INT32, _CfgParse_GetNumber},{CFG_TYPE_UINT, _CfgParse_GetNumber},{CFG_TYPE_UINT8, _CfgParse_GetNumber},
                        {CFG_TYPE_UINT16, _CfgParse_GetNumber},{CFG_TYPE_UINT32, _CfgParse_GetNumber},{CFG_TYPE_FLOAT, _CfgParse_GetNumber},
                        {CFG_TYPE_COMPLEX, _CfgParse_GetNumber},
                    };
                    for(int i = 0; i!= sizeof(TMP_STRUCT)/sizeof(TMP_STRUCT[0]); i++)
                    {
                        if(pcpd->type == TMP_STRUCT[i].type)
                        {
                            switch (TMP_STRUCT[i].fun(pcfg, pcpd))
                            {
                            case -1:case -2:
                                return -1;
                                break;
                            case EOF_OF_BUF: 
                                _CfgParse_SetRereadSign(pcfg);
                                break;;
                            case 0:
                                break;
                            }
                            break;
                        }
                    }
                }   break;
                case CFG_PARSE_STAGE_GROUP:
                    assert(pcpd && pcpd->type == CFG_TYPE_GROUP);
                    if(pcfg->parse.pbuf[pcfg->parse.posBuf] == '}')
                    {
                        DebugPrintf("End:group ,pos:%u\n",pcfg->parse.posBuf);
                        //结束 这个 group
                        pcfg->parse.pos++;pcfg->parse.posBuf++;
                        ((cfgdata_t*)pcpd->selfNode->data)->value.llval = pcpd->value.llval; //把 group 子元素数量保存到其中
                        Stack2Pop(&pcfg->parse.stackParseData);
                    }
                    else if((pcfg->parse.pbuf[pcfg->parse.posBuf] == ',' || (pcfg->parse.pbuf[pcfg->parse.posBuf] == ';')))
                    {
                        DebugPrintf("Next:group value ,pos:%u\n",pcfg->parse.posBuf);
                        //错误, 此时不应有分隔符，语法错误
                        pcfg->diagnosis.err = CFG_ERR_GROUP_NOT_ELEM;
                        pcfg->diagnosis.line = pcfg->parse.line;
                        pcfg->diagnosis.pos = pcfg->parse.pos;
                        return -1;
                    }
                    else 
                    {
                        switch (_CfgParse_GetKeywrods(pcfg, pcpd))
                        {
                        case -1: // 错误
                            return -1;
                            break;
                        case EOF_OF_BUF: 
                            _CfgParse_SetRereadSign(pcfg);
                            break;
                        case 0: // 成功，应新生成一个 cfgparsedata_t *
                        { //检查新生成的元素
                            cfgparsedata_t * pcpd_new = Stack2At(&pcfg->parse.stackParseData, -1);
                            if(pcpd_new->type == CFG_TYPE_STR)
                            {
                                pcpd_new->type = CFG_TYPE_NULL;
                            }
                            if(pcpd_new->type != CFG_TYPE_NULL || pcpd_new->sposKey == -1)
                            {
                                // 语法错误，要求键值对
                                pcfg->diagnosis.err = CFG_ERR_KV_NOT_KV;
                                pcfg->diagnosis.line = pcfg->parse.line;
                                pcfg->diagnosis.pos = pcfg->parse.pos;
                            }
                        }    
                            pcpd->value.llval++;
                            pcpd->stage = CFG_PARSE_STAGE_GROUP_SEPARATOR; //查换分隔符
                            break;
                        }
                    }
                    break;
                case CFG_PARSE_STAGE_GROUP_SEPARATOR:
                    assert(pcpd && pcpd->type == CFG_TYPE_GROUP);
                    if(pcfg->parse.pbuf[pcfg->parse.posBuf] == '}')
                    {
                        DebugPrintf("End:group ,pos:%u\n",pcfg->parse.posBuf);
                        //结束 这个 group
                        pcfg->parse.pos++;pcfg->parse.posBuf++;
                        ((cfgdata_t*)pcpd->selfNode->data)->value.llval = pcpd->value.llval; //把 group 子元素数量保存到其中
                        Stack2Pop(&pcfg->parse.stackParseData);
                    }
                    else if((pcfg->parse.pbuf[pcfg->parse.posBuf] == ',' || (pcfg->parse.pbuf[pcfg->parse.posBuf] == ';')))
                    {
                        DebugPrintf("Next:group value ,pos:%u\n",pcfg->parse.posBuf);
                        pcfg->parse.pos++;pcfg->parse.posBuf++;
                        pcpd->stage = CFG_PARSE_STAGE_GROUP;
                        continue;
                    }
                    else
                    {
                        //错误, 此时应有分隔符，语法错误
                        pcfg->diagnosis.err = CFG_ERR_GROUP_NOT_SPLITTER;
                        pcfg->diagnosis.line = pcfg->parse.line;
                        pcfg->diagnosis.pos = pcfg->parse.pos;
                        return -1;
                    }
                    break;
                case CFG_PARSE_STAGE_ARRAY:
                    assert(pcpd && pcpd->type == CFG_TYPE_ARRAY);
                    if(pcfg->parse.pbuf[pcfg->parse.posBuf] == ']')
                    {
                        DebugPrintf("End:array ,pos:%u\n",pcfg->parse.posBuf);
                        //结束 这个 group
                        pcfg->parse.pos++;pcfg->parse.posBuf++;
                        ((cfgdata_t*)pcpd->selfNode->data)->value.llval = pcpd->value.llval; //把 group 子元素数量保存到其中
                        Stack2Pop(&pcfg->parse.stackParseData);
                    }
                    else if((pcfg->parse.pbuf[pcfg->parse.posBuf] == ',' || (pcfg->parse.pbuf[pcfg->parse.posBuf] == ';')))
                    {
                        //错误, 此时不应有分隔符，语法错误
                        pcfg->diagnosis.err = CFG_ERR_ARRAY_NOT_ELEM;
                        pcfg->diagnosis.line = pcfg->parse.line;
                        pcfg->diagnosis.pos = pcfg->parse.pos;
                        return -1;
                    }
                    else
                    {
                        switch (_CfgParse_GetKeywrods(pcfg, pcpd))
                        {
                        case -1: // 错误
                            return -1;
                            break;
                        case EOF_OF_BUF: 
                            _CfgParse_SetRereadSign(pcfg);
                            continue;
                        case 0: // 成功，后面应跟
                            pcpd->value.llval++;
                            pcpd->stage = CFG_PARSE_STAGE_ARRAY_SEPARATOR; //查换分隔符
                            break;
                        }
                    }
                    break;
                case CFG_PARSE_STAGE_ARRAY_SEPARATOR:
                    assert(pcpd && pcpd->type == CFG_TYPE_ARRAY);
                    if(pcfg->parse.pbuf[pcfg->parse.posBuf] == ']')
                    {
                        DebugPrintf("End:array ,pos:%u\n",pcfg->parse.posBuf);
                        //结束 这个 group
                        pcfg->parse.pos++;pcfg->parse.posBuf++;
                        ((cfgdata_t*)pcpd->selfNode->data)->value.llval = pcpd->value.llval; //把 group 子元素数量保存到其中
                        Stack2Pop(&pcfg->parse.stackParseData);
                    }
                    else 
                    if((pcfg->parse.pbuf[pcfg->parse.posBuf] == ',' || (pcfg->parse.pbuf[pcfg->parse.posBuf] == ';')))
                    {
                        DebugPrintf("Next:array value ,pos:%u\n",pcfg->parse.posBuf);
                        pcfg->parse.pos++;pcfg->parse.posBuf++;
                        pcpd->stage = CFG_PARSE_STAGE_ARRAY;
                        continue;
                    }
                    else
                    {
                        //错误, 此时应有分隔符，语法错误
                        pcfg->diagnosis.err = CFG_ERR_ARRAY_NOT_SPLITTER;
                        pcfg->diagnosis.line = pcfg->parse.line;
                        pcfg->diagnosis.pos = pcfg->parse.pos;
                        return -1;
                    }
                    break;
                }
            }
        }
    }
    // 如果 读到结束 栈上还有数据说明没有读完
    return 0;
}

// cfgMap_t* cfg_set(cfg_t* pcfg,cfgMap_t* where, int aschild,  enum cfgKeywords type, char* key, void* value, unsigned int vlen)
// {
//     //检查 where的合法性
//     if(where)
//     {
//         if(NULL == _cfg_set_check_pmap(pcfg,where))
//         {
//             return NULL;
//         }
//     }
//     else
//     {
//         where = pcfg->cur;
//     }
//     // 先检查预分配空间是否有空闲空间，申请一个 新的空间
//     cfgMap_t* _pcm = _cfg_prealloc_map(pcfg,0);
//     if(_pcm == NULL) // 申请空间出错
//     {
//         return NULL;
//     }

//     if(aschild)
//     {
//         where->children = _pcm;
//         _pcm->prev = where;
//         _pcm->signEldest = 1;
//     }
//     else
//     {
//         where->next = _pcm;
//         _pcm->prev = where;
//         _pcm->signEldest = 0;
//     }
//     _pcm->children = NULL;
//     _pcm->type = type;
//     _pcm->key = key;
//     switch (type)
//     {
//     case CFG_KEYWORD_COMMENT: case CFG_KEYWORD_COMMENT_L:

//         _pcm->value.sval = (char *)malloc(vlen+1);
//         if(_pcm->value.sval == NULL)
//         {
//             //内存不足退出，
//             return NULL;
//         }
//         memcpy(_pcm->value.sval, value,vlen);
//         _pcm->value.sval[vlen] = 0;
//         break;
//     case CFG_KEYWORD_STR:
//         break;
//     default:
//         break;
//     }
//     pcfg->cur = _pcm;
//     return _pcm;
// }

cfgdata_t* CfgNodeData(treenode_t* node)
{
    return (cfgdata_t*)TreeNodeData(node);
}
treenode_t* CfgRoot(cfg_t* pcfg)
{
    return TreeRoot(pcfg->ptRoot) ;
}

treenode_t* CfgNodePparent(treenode_t* node)
{
    return TreeNodeParent(node);
}

treenode_t* CfgNodeChild(treenode_t* node)
{
    return TreeNodeChild(node);
}

treenode_t* CfgNodeNext(treenode_t* node)
{
    return TreeNodeNext(node);
}

treenode_t* CfgNodePrev(treenode_t* node)
{
    return TreeNodePrev(node);
}

#if defined(_WIN32) && defined(_MSC_VER)
#pragma warning( pop )
#elif defined(__linux__)
#endif